实模式 & 保护模式
Jan 22, 2020 20:30 · 1060 words · 3 minute read
CPU 有两种工作模式:实模式与保护模式。这两个模式的差别在于 CPU 对于内存的管理方式。在实模式下,CPU 直接通过物理地址访问内存;在保护模式下,CPU 通过地址映射表把虚拟的内存地址转换为物理的内存地址。
实模式
实模式基于 8086 和 8088 处理器。8086 是 16 位 CPU,能够执行 16 位指令并使用 20 根地址总线对 2^20 位也就是 1MB 内存进行寻址。
分段
但是 CPU 只有 16 位的寄存器和数据总线,怎么表示 20 位的内存地址呢?地址由段址和**偏址(逻辑地址)**组成(segment:offset),物理地址 = 段址 _ 16 + 偏移地址(二进制表示左移 4 位,十六进制表示左移 1 位)。通过这种分段技术,能够表示的最大内存地址为:FFFFh:FFFFh = FFFFh _ 16d + FFFFh = F,FFF0h + FFFFh = 10,FFEFh,后果是多出来 10,0000h ~ 10,FFEFh,当访问这些地址时,系统会回绕至 0h ~ FFEFh 而不认为越界,也就是所谓的 wrap-around。
CPU 实模式下,所有的软件甚至包括操作系统都在同一个物理地址空间下。操作系统可以如何分配内存?
- 把操作系统内存管理相关的函数地址,放到一个大家公认的地方(0x10000),每个软件要想申请内存就到这个地方取得内存管理函数并调用它。
- 把内存管理功能设计为一个中断请求,CPU 本身也提供了软中断(指令触发中断),比如我们约定 77 号中断为内存管理中断,操作系统在初始化时把自己的内存管理函数写到中断向量表的第 77 项。在 CPU 收到中断请求时,它会先停下手头的活来响应中断请求。
实模式下是没有多任务的,因为根本没有保护措施来阻止一个程序覆盖另一个程序,程序之间可以随意修改数据甚至程序指令。
保护模式
从 80286 开始,地址总线由原来的 20 跟增加到 24 根,保护模式出现了。80286 为了向下兼容,提供了一个 Gate A20 开关,也就是第 21 根地址线的控制线。因为有第 21 根地址线的存在,能够访问到实际的 10,0000h ~ 10,FFEFh 地址的内存而不是回绕。保护模式下 Gate A20 一定是打开的。
从 80386 开始,CPU 进入 32 位时代,内存能够寻址的空间更大了,提升至 2^32 位也就是 4GB。
分段
本质上是将内存切成不等长的单元(段),实模式下的段是固定的 2^16 位也就是 64k。既然大小不固定,所有段的所有信息都被存在**全局段描述符表(GDT)**中,而 GDT 本身被建立在内存中。CPU 中有个特殊的 48 位寄存器 GDTR 用来存储段描述符表所在的内存地址(用掉 32 位),剩下的 16 位存表大小。
每个段描述符长 64 位:
- 段址
- 段大小
- 访问权限(保护机制)
- 控制位
在实模式下,CPU 中的段寄存器存储的是真实的段基址;在保护模式下,段寄存器就变成了段选择子(相当于数组索引),指向某个段描述符,实现不同进程的切换。