实模式寻址与保护模式寻址
本文最后更新于 2024年6月7日 下午
实模式寻址
8086/8088处理器只能在实模式下进行寻址
实模式寻址是为了解决16位字长的机器访问20位地址的问题,而解决的方法就是采用寄存器分段的方式。
因为机器字长为16位,故此一个段的最大大小为2的16次方,也即64K,但不是说段的的大小一定为64K。
段不能起始于任意位置,段必须起始于小段的的整数倍位置,小段的大小为16字节。在1MB的内存中存在64K个小段。这64K个小段用16位二进制就可以唯一标识,而小段内的16个字节可以用4位二进制标识。16+4便构成了20位地址。
但这20位地址如何计算得出呢?
以程序段为例,CS寄存器内保存着16位的段地址(XXXXH),IP寄存器内保存着16位的偏移量(YYYYH),将CS寄存器的16地址左移4位得到(XXXX0H)与偏移量相加即可得到最终的20位物理地址。
在操作系统中,段的存储地址的分配是由操作系统完成的,每个段可以独立的占有64KB的区域,但是各段也可以发生重叠。
例:某程序的代码段需要8KB的存储区,数据段需要2KB的存储区,那么在在代码段结束后的第一个小段就可以作为数据段的起始地址,这样看来代码段的64KB与数据段的64KB是有重叠的,这是由于段的大小是根据实际需要来分配的不一定真的占有64KB。
但这时可能会有人有疑问,如果一个段的大小超过64KB或者需要访问其他段的内容怎么办呢?其实这时候就需要动态的修改段寄存器的内容来实现了。
保护模式寻址
除8086/8088处理器以外的处理器都可以在实模式和保护模式下寻址
处理器开机时首先进入实模式寻址方式,然后再从实模式向保护模式转换
过程:建立总体描述符表 (Global Descriptor Table GDT) 或本地描述符表 (Local Descriptor Table LDT),并在 CPU 的机器字 (machine status word MSW) 中启动保护模式
- GDT:存放任何程序的段信息
- LDT:存放特定程序的段信息
在80286与80386下段寄存器仍然为16位,在保护模式下所有的段寄存器(CS,DS,ES,FS,GS)中存放的都是段选择子,段选择子依然是一个16位的二进制数。
段选择子结构:
前13位段选择符在段表中的索引,第14位为描述符表标识位,最后2位为请求等级标志位。通过段选择子可以找到对应的描述符表。
但描述符表中的段描述符在80286与80386下不同:
导致后续的计算物理地址上存在差异:
80286使用2,3,4字节,共24位作为段基地址。使用该24位地址与32位虚拟地址相加得到最终的线性地址。
虽然286只有24位地址线但是可以通过,映射外存的方式得到,虚拟出32位地址线
80386使用2,3,4,7字节,共32位作为基地址。使用这32位形成的地址与32位线性地址相加得到的即为32位线性地址。
线性地址还需经过分页寻址最终转换为物理地址
分页寻址的部分可以参照 分页寻址