8086 (实模式)
- 通用寄存器:AX、BX、CX、DX、SI、DI、BP和SP,此外前4个寄存器可以分成高8位和低8位来访问,AH、AL、BH、BL、CH、CL以及DH、DL
- 4个16位的段寄存器:CS、DS、SS、ES,其中CS存放指令的段地址,DS和ES存放数据的段地址,默认是DS,要使用ES需要在指令里指明,SS存放栈的段地址
- 基址寄存器BX用的是DS,基址寄存器BP用的是SS。
- 基址变址:[BX]、[BX+SI]、[BX+DI]、[BP]、[BP+SI]、[BP+DI]
- 不支持将数据直接使用mov的方式送入段寄存器,比如mov ds,1000H,需要通过一个通用寄存器来进行中转
- “段地址x16+偏移地址=物理地址”含义:CPU在访问内存时,用一个基础地址(段地址x16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
- 正确理解段地址:内存并没有分段,段的划分来自于CPU,由于8086用“基础地址(段地址x16)+ 偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存
- 由于乘以16的缘故,基础地址总是16字节对齐的
- 任意时刻,CPU将CS:IP指向的内容当作指令执行
- 上电后,CS的初始值为0xFFFF,IP的默认值为0x0000,所以CPU从内存0xFFFF0读取指令执行
- CS和IP的值不能通过mov来修改,需要通过转移指令,如“jmp 段地址:偏移地址”
- 执行mov ax, [2] 表示: 将 ds x 16 + 2 这个内存单元的值读到ax寄存器中
- 在任意时刻,SS:SP指向栈顶元素,执行push ax时,首先SP=SP-2,然后将ax中的内容送入SS:SP指向的内存单元处,此时SS:SP指向新栈顶。pop的过程与之相反。
IA-32 (保护模式)
- 通用寄存器:EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP
- 段寄存器不再存放段基地址,而是段的选择子或者段选择器,即用于选择所要访问的段
- 逻辑地址:段地址:偏移地址
- 线性地址:段地址x16 + 偏移地址
- 虚拟地址:逻辑地址和线性地址都是虚拟地址的表现形式
- 物理地址:实模式和非分页保护模式下就是线性地址,分页保护模式下需要经过MMU将线性地址转换为物理地址
- 在保护模式下,对内存的访问仍然使用段地址和偏移地址,但是在每个段能够访问之前,必须先进行登记。登记的信息包括:段的起始地址、段的界限等各种访问属性。每个登记信息占用8字节,称为段描述符,每个段都需要一个描述符。描述符存放在一段内存中,这段内存中,所有的描述符都挨在一起,集中存放,构成了一个描述符表。
- 最主要的描述表是全局描述符表GDT,进入保护模式前,必须要定义全局描述符表。全局描述符表寄存器GDTR,这个寄存器为48位,高32位保存全局描述符表在内存中的起始线性地址,低16位表示全局描述符表的边界(界限),其数值上等于表的大小(总字节数)-1. 所以全局描述符表最大为64KB,最多容纳8192个描述符。