x86 汇编/保护模式
本页将讨论 x86 处理器中实模式和保护模式操作之间的区别。它还将讨论如何进入保护模式以及如何退出保护模式。现代操作系统 (Windows、Unix、Linux、BSD 等) 都是在保护模式下运行的,因此大多数汇编语言程序员不需要这些信息。但是,这些信息对于尝试编写内核或 引导加载程序 的人来说特别有用。
当 x86 处理器通电或复位时,它处于实模式。在实模式下,x86 处理器本质上就像一个非常快的 8086。只能使用处理器的基本指令集。实模式内存地址空间限制为 1 MiB 可寻址内存,每个内存段限制为 64 KiB。实模式本质上是为了与 8086 和 80186 程序向后兼容而提供的。
在保护模式下,x86 可以寻址 4 GB 的地址空间。这可能直接映射到物理 RAM(在这种情况下,如果 RAM 小于 4 GB,则某些地址空间未使用),或者可以使用分页在虚拟地址和物理地址之间进行任意转换。在保护模式下,内存中的段可以分配保护,尝试违反此保护会导致“一般保护”异常。
386 中的保护模式,除其他事项外,由控制寄存器控制,这些寄存器分别标记为 CR0、CR2、CR3 和 CR4。
286 中的保护模式由机器状态字控制。
长模式由 AMD 随着 Athlon64 处理器的出现而引入。长模式允许微处理器访问 64 位内存空间并访问 64 位长寄存器。许多 16 位和 32 位指令在长模式下不起作用(或无法正常工作)。处于实模式的 x86-64 处理器与 16 位芯片的行为完全相同,处于保护模式的 x86-64 芯片与 32 位处理器的行为完全相同。要解锁芯片的 64 位功能,必须将芯片切换到长模式。
控制寄存器 CR0 的最低 5 位包含 5 个标志,这些标志决定了系统的运行方式。此状态寄存器有一个我们特别感兴趣的标志:“保护模式启用”标志 (PE)。以下是进入保护模式的一般步骤
- 创建一个有效的 GDT (全局描述符表)
- 创建一个 6 字节伪描述符来指向 GDT
-
- 如果将使用 分页,请使用有效的页表、PDBR 或 PML4 加载 CR3。
- 如果将使用 PAE(物理地址扩展),请设置 CR4.PAE = 1。
- 如果切换到长模式,请设置 IA32_EFER.LME = 1。
- 禁用中断 (CLI)。
- 加载一个具有空限制的 IDT 伪描述符(这可以防止在保护模式下使用实模式 IDT)
- 设置 MSW 或 CR0 寄存器的 PE 位(如果将启用分页,则设置 PG 位)
- 执行远跳转(如果切换到长模式,即使目标代码段是 64 位代码段,偏移量也不能超过 32 位,因为远跳转指令是在兼容模式下执行的)
- 使用有效的选择器加载数据段寄存器,以防止中断发生时出现 GP 异常
- 使用有效的堆栈加载 SS:(E)SP
- 加载指向 IDT 的 IDT 伪描述符
- 启用中断。
以下部分将详细介绍这些步骤。
要在 64 位 x86 处理器 (x86-64) 上进入长模式
- 如果启用了分页,请禁用分页。
- 如果 CR4.PAE 尚未设置,请设置它。
- 设置 IA32_EFER.LME = 1。
- 使用有效的 PML4 表加载 CR3。
- 启用分页。
- 此时,您将处于兼容模式。可以执行远跳转以切换到长模式。但是,偏移量不能超过 32 位。
CR 寄存器的许多位仅影响保护模式下的行为。
CR0 32 位寄存器有 6 个我们感兴趣的位。CR0 寄存器的低 5 位和最高位。以下是 CR0 的表示
CR0: |PG|----RESERVED----|NE|ET|TS|EM|MP|PE|
- PE
- 位 0。保护环境标志。当设置此标志时,系统将进入保护模式。
- MP
- 位 1。监控协处理器标志。此标志控制“WAIT”指令的操作。
- EM
- 位 2。仿真标志。当设置此标志时,协处理器指令将生成异常。
- TS
- 位 3。任务切换标志。当处理器切换到新任务时,此标志会自动设置。
- ET
- 位 4。扩展类型标志。ET(也称为“R”)告诉我们安装了哪种类型的协处理器。如果 ET = 0,则安装了 80287。如果 ET = 1,则安装了 80387。
- NE
- 位 5。新的异常。如果此标志未设置,FPU 异常将作为中断到达。如果设置,则作为异常。
- PG
- 位 31。分页标志。当设置此标志时,将启用内存分页。我们稍后将详细讨论。
CR2 包含一个称为页错误线性地址 (PFLA) 的值。当发生页错误时,将在 CR2 中存储尝试访问的地址。
CR3 的高 20 位称为页目录基址寄存器 (PDBR)。PDBR 保存页目录的物理地址。
CR4 包含几个标志,这些标志控制处理器的增强功能。
分页是微处理器可以执行的一项特殊工作,以使系统中可用内存量看起来比实际更大且更动态。在分页系统中,一定的空间可能在硬盘驱动器 (或任何辅助存储) 上留出,称为交换文件或交换分区。系统的虚拟内存是程序可以访问的一切,例如内存,包括物理 RAM 和交换空间。
总的虚拟内存被分成块或页,每个页面通常为 4096 字节(尽管在不同的系统上这个数字可能不同)。这些页面可以在虚拟内存中移动,页面内的所有指针将通过引用全局分页目录(微处理器维护)自动指向新位置。当前分页目录的指针存储在 CR3 寄存器中。
当系统尝试从分页目录/表中标记为“不存在”的页面读取时,当系统尝试将数据写入当前可用页面的边界之外时,或者当分页系统中发生任何其他错误时,就会发生页面错误。当发生页面错误时,访问的内存地址将存储在 CR2 寄存器中。
除了实模式、保护模式和长模式之外,x86 处理器还可以进入其他模式,用于不同的用途。
- 虚拟 8086 模式:在这种模式下,为在实模式下运行而编写的应用程序软件在受保护模式的多任务操作系统监控下执行。
- 系统管理模式:这种模式使处理器能够执行系统任务,如电源管理,而不会干扰操作系统或其他软件。