chap2.6_保护模式
保护模式
保护模式寻址方式
1. 实模式下寻址的缺陷
2.保护模式下寻址
实模式下使用的是段寄存器(16位) << 4 + 偏移地址方式来寻址。
保护模式和实模式下的完全不一样。
保护模式下寻址方式
1)首先内存中建立一个GDT全局分段描述表。
2)DS中不再是内存的段开始地址,而是GDT表的索引。
3)寻址时,首先根据DS的高13位的值得到一个索引,然后查找到在GDT中对应的一个全局分段描述。再根据这个描述来定位到段的开始位置。
4)找到GDT段之后,继续根据偏移地址,在GDT段内进行内存寻址。
段的跳转指令
JMP 段选择子:偏移地址
1)加载段选择子到CS段寄存器
2)获取段选择子索引号,根据索引号查找GDT表,加载GDT段描述符到CS段寄存器的描述符缓存
3)加载偏移地址到EIP寄存器
4)根据 CS段寄存器的描述符缓存 和 EIP寄存器 寻址。
最后跳转位置是
内存地址:段基本地址(根据段选择子获取) + 偏移地址
保护模式下的段
- 段选择器
保护模式下,段寄存器CS,DS,ES,,FS,GS,SS,称之为段选择器。
段选择器中的数据称为段选择子
段选择子 : 描述符索引(13位) | TI | RPL
其中
- 描述符索引:GDT描述符表中的描述符的索引号(从0开始:0,1,2,3…)
- TI: TI = 0 表示GDT描述符, TI =1 表示LDT描述符
- RPL: 请求权特级:
当我们跳转到段的时侯,实际上是段选择器赋值为以上格式的值即可。

实模式和保护模式的区别
在计算机加载完成后,在实模式执行完一些初始化和加载工作。然后CPU设置进入保护模式。可以使用16位的数据。。
为了突破实模式1M内存寻址的限制,使用到更多内存。于是出现了保护模式,保护模式下,通过开启A20总线,可以使用32位的寄存器操作,其实访问地址已经达到了1<<32=4G内存。
实模式与保护模式的最大区别就是寻址方式:
1)保护模式不再使用段寄存器 <<4 +偏移地址的方式寻址,通过建立分段表将内存分成段。寻址时先加载分段表进入不同的段位置,然后在当前段内继续进行内存寻址。
2)保护模式不能使用BIOS中断
进入保护模式
[TOC]
进入保护模式
进入保护模式的步骤:
- 关闭中断,打开地址线A20GATE,使得CPU可以访问1M以上的内存空间。
- 设置CR0寄存器,进入保护模式。
- 加载临时GDT
- 进入保护模式后,首先执行jmp指令。因为内存寻址方式改变,需要刷新指令流水线
打开A20Gate
1. A20Gate的作用
在实模式下,A20Gate是关闭的,意味着只能使用20根地址线,需要通过打开A20Gate,访问第21根以上的总线。
A20Gate关闭时侯的内存访问:
在8088 CPU下, 只能使用20根总线 .
因此,初始化时, A20Gate关闭式,使用20根总线. 所以寻址范围位 0x00000 ~ 0xFFFFF,总共1M的地址范围。
当访问的地址大于这个范围,高位的值将被截取掉,导致超出1M的地址访问会使得CPU回滚到1M内地址范围的现象
例如:
当使用 [0xFFFF :0xFFFF ] 内存地址,得到的地址位 0x10FFEF 。但是在实模式下,由于20根总线的限制,最高位的1是无效的,实际的访问地址
回绕到[0x0FFEF]。
A20Gate打开后的内存访问:
后期,80286使用24根总线,而80286有24根总线,80386有32位总线.
打开A20Gate, 可以使用到32位的地址总线,内存地址访问也达到了1<<32 的4G范围。
实际上开启A20Gate,总线的寻址能力达到了4G,但是cpu的内存访问能力因为16位段寄存器,和16位偏移地址的限制,并不能协调工作。
A20Gate打开后, 还需要进入保护模式, 建立GDT描述名, 进行段地址 和 内存的映射关系, 使用新的内存地址访问方式 . 突破cpu的内存访问限制。
2. 开启A20Gate
开启A20Gate,只要设置io端口0x92的第一位为1就可以了。
1 | ;------------------ |
设置CR0寄存器,进入保护模式
CR0寄存器

CR0寄存器是一个32位的寄存器
第0位-PE位:
Protection Enable(保护使能)是CR0寄存器的第0位(bit 0)。当设置了PE标志时,启用保护模式;当清除PE标志时,启用实地址模式。该标志位并不直接启用分页机制,它仅启用段级别的保护。要启用分页,必须同时设置PE和PG标志。
第1位-MP位:
Monitor Coprocessor(监视协处理器)是CR0寄存器的第1位(bit 1)。它控制WAIT(或FWAIT)指令与TS标志(CR0的第3位)的交互作用。如果设置了MP标志,并且TS标志也被设置,那么WAIT指令将引发设备不可用异常(#NM)。如果清除了MP标志,则WAIT指令将忽略TS标志的设置。
第16位-WP位:
Write Protect(写保护)是CR0寄存器的第16位(bit 16)。当设置了WP标志时,阻止特权级程序对只读页面进行写操作;当清除WP标志时,允许特权级程序对只读页面进行写操作(不考虑U/S位的设置)。该标志有助于实现创建新进程(forking)时使用的写时复制(copy-on-write)方法,该方法在UNIX等操作系统中被使用。在软件可以设置CR4.CET之前,必须设置此标志,并且只要CR4.CET = 1,就不能清除该标志。
第18位-AM位:
Alignment Mask(对齐掩码)是CR0寄存器的第18位(bit 18)。当设置了AM标志时,启用自动对齐检查;当清除AM标志时,禁用对齐检查。对齐检查仅在满足以下条件时进行:AM标志被设置、EFLAGS寄存器中的AC标志被设置、CPL(当前特权级)为3,并且处理器处于保护模式或虚拟8086模式下。
第31位-PG位:
Paging(分页)标志位是CR0寄存器的第31位。当该位被设置时(为1时),启用分页机制;当该位被清除时(为0时),禁用分页机制。当分页被禁用时,所有线性地址都被视为物理地址。也就是说没有分页机制,段机制通过段基址加偏移后就是真实物理地址,如果PE标志(寄存器CR0的第0位)未设置,PG标志则没有影响;在PE标志被清除时设置PG标志会导致通用保护异常(#GP)。
设置CR0寄存器的最高位为0,最低位为1,则可以进入保护模式。
CR0寄存器的作用
- 改变段寻址方式,使用段描述符方式寻址。
- 实模式指令的操作数默认为16位,保护模式指令的操作数默认为32位。
代码:
1 | ;------------------ |
loader.asm完整代码如下
1 | ; RAST LOADER |
使用bochs调试
在0x7c00打断点,输入c跳转执行
$ pb 0x7c00
$ c
输入显示切换模式命令
$ show mode
输入c继续执行
$ c
可以看到控制他输出:
00017609546: switched from ‘real mode’ to ‘protected mode’
说明系统成功的从实模式切换到保护模式

查看CR0的PE位: 值为1
$ creg

保护模式内存分配
| 内存区域 | 大小 | 数据内容 | 说明 |
|---|---|---|---|
| 0x7C00 - 0x7DFF | 512B | boot.bin | 引导扇区的内存地址 |
| 0x8000 - 0x81FF | 512B | loader.bin | loader内存位置 |
| 0x8200 - 0xC200 | 16KB | kernel.bin | kernel内存位置 |
| 0x10000 - 0x8FFFF | … | … | 空白(执行loader程序) |
| 0x90000 - 0x9FFFF | 系统信息 | 内存信息 | |
| 0xA0000 - 0xFFFFF | 显示 | 显存地址(默认使用0xB8000 - 0xBFFFF) | |
| … | … | ||
| 0x100000-0x101000 | 4KB | 页目录 | 1MB内存位置 |
| 0x101000-0x200000 | 页表 | 页表信息 | |