实模式寻址方式

在上《操作系统高级教程》课时有BIOS启动时的实模式,讲到 CS与IP这两个寄存器,但是始终不能理解为什么说CS:IP可以表示一个物理地址,查询后才理解到与实模式的寻址方式有关。

8086的寻址方式

为了理解实模式,首先需要理解Intel 8086这个16位CPU的寻址模式。

8086的CPU是16位,即它的所有寄存器和寄存器之间的数据总线都是16位的,而其外部数据总线却是20位的。那么如何才能访问到20位也就是1MB的地址空间呢?显然一个寄存器是不够的所以就用两个寄存器来存储,这也就是段式寻址(内存分段)。段式寻址需要使用一个寄存器作为段寄存器比如CS代码段寄存器,使用另外一个寄存器比如IP指令指针寄存器作为偏移寄存器。计算物理地址的时候首先将段寄存器的16位地址向左移动4位(也就是最开始段寄存器的地址x16),然后将左移4位后的段地址与偏移地址相加就可以得到一个20位的物理地址了。也可以理解成最开始的段寄存器的地址默认后面还有4位,只是都省略成0,这样就可以放在16位寄存器中了。

实模式寻址方式

实模式(Real mode) 是Intel 80286和之后的80x86兼容CPU的操作模式,所有的80x86CPU的开机状态都是实模式。实模式的特性是一个20位的存储器地址空间(即1MB的存储器)可以被寻址。为了兼容,也为了解决最开始的启动问题,Intel将所有80x86系列的CPU(包括最新型号的64位CPU)的硬件都设计为加电即进入16位实模式状态运行。在实模式状态下寄存器是16位的,地址总线是20位的,也就是说实模式下寻址空间为1MB。因此与8086这个16位机器一样,为了实现20位寻址依然采取段式寻址方式。

开机时的第一个操作就是执行BIOS程序,CPU的硬件逻辑被设计为加电瞬间强行将CS的值设置为0XF000,IP的值设置为0XFFF0,这样CS:IP 的地址就是CS值左移四位变成0xF0000后加上IP的偏移地址也就是0xF0000+0XFFF0 也就是0xFFFF0,而0xFFFF0这个地址也就是BIOS程序的地址,CPU将开始执行这个地址的BIOS代码,从而开始BIOS的启动。

参考

《Linux内核设计的艺术》第二版

https://zh.wikipedia.org/wiki/X86#%E7%9C%9F%E5%AF%A6%E6%A8%A1%E5%BC%8F

https://zh.wikipedia.org/wiki/Intel_8086#%E5%86%85%E5%AD%98%E5%88%86%E6%AE%B5

https://zhuanlan.zhihu.com/p/69504370

https://blog.csdn.net/unix21/article/details/8450214