(八)内存分段管理
1.物理地址=基础地址(段地址*0x10)+偏移地址
所以采用分段的内存管理:
2.在编程时可以根据需要,将若干连续地址的内存单元看做一个段,用段地址×16定为段的起始地址(基础地址),用偏移地址定位段中的内存单元。
->段地址×16必然是16的倍数,所以一个段的起始地址(基础地址)也一定是16的倍数
->偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB
结论:偏移地址:0-0xFFFF 64KB个内存单元,加入给的段地址为0x10000 CPU寻址范围为0x10000-0x1FFFF
(九)段寄存器
以8086CPU为例:
8086有4个段寄存器:CS、DS、SS、ES,当CPU需要访问内存时由这4个段寄存器提供内存单元的段地址
->CS (Code Segment):代码段寄存器
1.CS为代码段寄存器,IP为指令指针寄存器,它们指示了CPU当前要读取指令的地址:例如
->CS:IP : 2000H:0000H
->执行mov ax,0123H -> AX:0123H -> CS:IP : 2000H:0003H
->执行mov bx,0003H -> BX:0003H -> CS:IP : 2000H:0006H
->执行mov ax,bx -> AX:0003H -> CS:IP 2000H:0008H
->执行add ax,bx -> AX:0006H ->CS:IP 2000H:000AH
.........
在内存或者磁盘上,指令和数据没有任何区别,都是二进制信息,CPU将CS:IP指向的内存单元的内容看做指令
2.jmp指令
mov指令不能用于设置CS、IP的值,8086提供了另外的指令来修改CS、IP的值,这些指令统称为转移指令,最简单的是jmp指令:
练习:
-> CS:IP 2000H:0000H -> 执行20000H处指令 -> mov ax,6622H -> AX:6622H -> CS:IP 2000H:0003H
-> 执行20003H处指令 -> jmp 1000:3 -> CS:IP 1000H:0003H
-> 执行10003H处指令 -> mov ax,0000 -> AX:0000H ->CS:IP 1000H:0006H
-> 执行10006H处指令 -> mov bx, ax ->BX:0000H ->CS:IP 1000H:0008H
-> 执行10008H处指令 -> jmp bx -> CS:IP 1000H:0000H
-> 执行10000H处指令 -> mov ax 0123H ->AX:0123H -> CS:IP 1000H:0003H
-> 开始陷入死循环
由此可以看出,每次读取命令CPU会改变一次IP,执行到jmp时会多改变一次IP。
->DS (Data Segment):数据段寄存器
1.DS [address]
CPU要读写一个内存单元时,必须要先给出这个内存单元的地址,在8086中,内存地址由段地址和偏移地址组成8086中有一个DS段寄存器,通常用来存放要访问数据的段地址
-> mov bx,1000H
-> mov ds,bx
-> mov al,[0]
*上面3条指令的作用将10000H(1000:0)中的内存数据赋值到al寄存器中
*mov al,[address]的意思将DS:address中的内存数据赋值到al寄存器中
*由于al是8位寄存器,所以是将一个字节的数据赋值给al寄存器
练习1:写出下面指令执行后寄存器ax,bx,cx中的值
1.AX: 1000H
2.DS: 1000H
3.AX: 1123H
4.BX: 6622H
5.CX: 2211H
6.BX: 8833H
7.CX:8833H
----> AX:1123H BX:8833H CX:8833H
练习2:写出下面指令执行后寄存器ax,bx中的值
1.AX 1000H
2.DS 1000H
3.AX 11316 = 2C34H
4.10000H:34 10001H:2C 10002H:22 10003H:11
5.BX 2C34
6.10000H:34 10001H:2C 10002H:22 10003H:11
7.BX 1B12
8.10000H:34 10001H:2C 10002H:12 10003H:1B
指令的概念:
练习:
各寄存器的初始值:CS=2000H,IP=0,DS=1000H,AX=0,BX=0;
1.写出CPU执行的指令序列(用汇编指令写出)
2.写出CPU执行完指令后,CS,IP和相关寄存器中的数值
3.再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些又是程序?
以上。
->SS (Stack Segment):堆栈段寄存器
->ES (Extra Segment):附加段寄存器