- 1 基本模式
- 1.1 传统IA-32模式
- 1.2 IA-32e模式
- 2 基本寄存器组
- 3 权限控制
- 3.1 段保护
- 3.2 页保护
从CPU角度来看, 程序就是一组指令并按编译时生成的顺序执行. 执行的过程中会从内存中取值(!!!)并在寄存器中操作(!!!), 以得到期望的结果. 此外, 还有一些特殊的寄存器对CPU的状态和行为进行控制.
1 基本模式
实际上, x86有五种运行模式: 实模式、保护模式、长模式、SMM模式和虚拟8086模式。
具有64位扩展技术的处理器可以运行在传统的IA-32模式和IA-32e 模式下,而这些模式也都有自己的子模式,在此对它们进行简要介绍,以方便读者理解x86 CPU的工作。
1.1 传统IA-32模式
传统的IA-32模式下,x86有三种运行模式:实模式、保护模式和虚拟8086模式。
- 实模式:是Intel 8086处理器工作的模式。在该模式下,逻辑地址转换后就是物理地址,操作系统或BIOS通常在该模式下准备必要的数据结构和初始化关键的寄存器,然后再切换入保护模式。
- 保护模式:操作系统运行时最常用的模式。在该模式下,CPU的所有功能几乎都能得到使用,可以访问架构允许的所有物理地址空间。
- 虚拟 8086模式:该模式让 CPU在保护模式下为 8086程序虚拟实模式的运行环境,使这些程序在执行时无须从保护模式切换到实模式。
1.2 IA-32e模式
IA-32e 模式是x86在运行64位操作系统的时候使用的一种模式。带有64位扩展技术的处理器初始进入传统的页式地址保护模式,然后 PAE 模式被使能。IA-32e模式只能在装载64位操作系统的情况下进入,它包含两个子模式:64位模式和兼容模式。
1)64位模式用于运行在 64位操作系统上的 64位应用程序。它支持的特性如下:
-
64位线性地址结构。
-
现有的通用寄存器!!! 被加宽到64位(RAX、RBX、RCX、RDX、RSI、RDI、RBP、RSP)。
-
新增了8个通用寄存器(R8~R15)。
-
新增了8个128位流SIMD扩展寄存器(XMM8~XMM15)。
-
一个64位的指令指针(RIP)和一个新的RIP相关数据寻址模式。
-
对单一的代码、数据和栈空间能用平板地址空间。
-
扩展指令和新指令。
-
支持大于64GB的物理地址。
-
新的中断优先级控制机制。
2)兼容模式允许传统的 16位和 32位应用程序无须重新编译便运行在 64位操作系统下,然而虚拟8086模式!!!、任务切换!!! 和栈参数复制特性!!! 在兼容模式下不被支持!!!。
表1-1列出了目前x86-64所支持的模式及这些模式的特点。
表1-1 x86-64所支持模式的特点总结
 根据表1-1,我们可以看出,在传统模式下,x86-64的CPU工作模式与传统的IA-32完全相同。
在长模式下,x86-64对16位和32位代码进行了兼容(即兼容模式)。即使CPU上运行64位操作系统,传统的16位和32位代码也能在操作系统上运行。而且,由于x86-64兼容IA-32指令,这些代码在兼容模式下运行基本没有性能损耗。
2 基本寄存器组
以32位为例介绍, 寄存器是软件操作CPU的最基本的部件, x86架构的寄存器可粗略分为下面几类.
⓵ 通用寄存器: 共8个32位通用寄存器, 用来保存程序运行时的临时变量、栈指针等数据.
⓶ 内存管理寄存器: 包含段寄存器和描述符表寄存器.
⓷ EFLAGS寄存器: 32位的寄存器, 用来保存程序运行中的一些标志位信息, 如溢出、开启中断与否、分支跳转等信息
⓸ EIP寄存器: 32位的寄存器, 用来保存指向当前指令的地址. 通常称为PC指针.
⓹ 浮点运算寄存器: 对于浮点运算(!!!), x86指令会通过一个浮点运算协处理器(!!!)来处理. 协处理器包含8个80位的浮点数据寄存器, 1个16位的控制寄存器, 1个16位的状态寄存器, 1个16位的标志寄存器, 1个11位的指令码寄存器, 1个48位浮点指令指针寄存器和1个48位的浮点数据指针寄存器. 这些浮点运算寄存器为浮点运算提供一个基本运行环境.
⓺ 控制寄存器: x86提供了5个控制寄存器, 分别是CR0~CR4寄存器. 这些控制寄存器决定了CPU运行的模式和特征等. x86-64的64位模式引入了CR8,它被定义为任务优先级寄存器(TPR!!!),操作系统能够基于中断的优先级别使用TPR来控制是否允许外部中断来中断处理器。
⓻ 其它寄存器: x86还提供了其它的一些寄存器, 包括8个调试寄存器(DR0~DR7)、内存区域类型寄存器(MTRR)、机器检查寄存器(Machine Check Registers)以及性能监控寄存器.
表 1-2 对运行在 64 位模式下的应用程序和运行在传统的 IA-32 环境下的应用程序中的一些寄存器数据结构进行对比分析。传统的IA-32环境包括那些存在于现有IA-32处理器中的传统模式、支持64位扩展技术的处理器中的兼容模式。
3 权限控制
权限控制是指CPU对资源进行分类, 使不同权限的程序只能访问自身权限允许访问的资源. 操作系统的用户态和内核态是最常见的权限控制, 内核态程序具有最高权限, 用户态程序具有最低权限. x86有两种权限控制机制: 段保护和页保护. 这两种机制分别对应了内存管理中的段机制和分页机制.
3.1 段保护
三种属性
⓵ 当前权限级别(Current Privilege Level, CPL): CPL代表当前运行的代码的权限. 通过CS的0、1位记录代码的CPL值, CPL可以有0~3共4个级别. Ring0对应CPL=0, 具有最高权限, 操作系统内核运行在该权限; Ring3对应CPL=3, 用户程序运行在Ring3. CPL值越高权限越低.
⓶ 描述符权限级别(Descriptor Privilege Level, DPL): DPL代表段和门所具有的权限. 代表了代码访问某个段或某个门时所需的最低权限!!!. 例如, 某个数据段描述符有DPL=2, 则只有CPL=0、1、2的代码可以访问该数据段, CPL=3的不能访问.
⓷ 所要求的的权限级别(Requested Privilege Level, RPL): RPL比较特殊, 存在于段寄存器的0~1位(注意, CS寄存器的0~1位是CPL)
3.2 页保护
思想比较简单, 通过在页目录项、页表项中引入了一个User/Supervisor位, 将页面(或整个页目录项)分为User和Supervisor两个特权级.
- 该位为0时表示Supervisor模式, 对应CPL=0、1、2的情况;
- 为1表示User模式, 对应CPL=3的情况.
当程序运行在CPL=0、1、2, 也就是Supervisor模式下时, 可以访问所有页面; 运行在CPL=3下的程序处于User模式, 只能访问User页面.
段保护和页保护是可以混用的, 从而带来更为灵活的保护机制.