控制寄存器

什么是控制寄存器

控制寄存器是一个用于控制和确定处理器的操作模式以及当前执行任务的特性的寄存器。

image-20201110145010137

控制寄存器在x86下一共有5个(CR0~CR4),其中CR1保留不用。

  • CR0 – 总闸
  • CR2 – 缺页异常
  • CR3 –页目录表基址
  • CR4 – 分闸

CR0 – 总闸

image-20201110173652554

名称 说明
PE 0 Protection Enable开启段保护 (没有开启页保护)
MP 1 监控协处理器(Monitor coProcessor或Math Present)标志。用于控制WAIT/FWAIT指令与TS标志的交互作用。如果MP=1、TS=1,那么执行WAIT指令将产生一个设备不存在异常;如果MP=0,则TS标志不会影响WAIT的执行。
EM 2 (EMulation)标志。当该位为1时,表示处理器没有内部或外部协处理器,执行协处理器指令时会引起设备不存在异常;当为0时,表示系统有协处理器。设置这个标志可以迫使所有浮点指令使用软件来模拟。此标志还会影响MMX/SSE/SSE2/SSE3/SSSE3/SSE4 指令。
TS 3 任务已切换(Task Switched)标志。该标志用于推迟保存任务切换时的协处理器内容,直到新任务开始实际执行协处理器指令。处理器在每次任务切换时都会设置该标志,并且在执行协处理器指令时测试该标志。任务段切换时置1,回来时清零。
ET 4 扩展类型(Extension Type)标志。当该标志为1时,表示指明系统中有80387协处理器,并使用32位协处理器协议。ET=0指明使用80287协处理器。如果仿真位EM=1,则该位将被忽略。在处理器复位操作时,ET位会被初始化指明系统中使用的协处理器类型。如果系统中有80387,则ET被设置成1,否则若有一个80287或者没有协处理器,则ET被设置成0。
NE 5 对于Intel 80486或以上的CPU,CR0的位5是协处理器错误(Numeric Error)标志。当设置该标志时,就启用了x87协处理器错误的内部报告机制;若复位该标志,那么就使用PC形式的x87协处理器错误报告机制。当NE为复位状态并且CPU的IGNNE输入引脚有信号时,那么数学协处理器x87错误将被忽略。当NE为复位状态并且CPU的IGNNE输入引脚无信号时,那么非屏蔽的数学协处理器x87错误将导致处理器通过FERR引脚在外部产生一个中断,并且在执行下一个等待形式浮点指令或WAIT/FWAIT指令之前立刻停止指令执行。CPU的FERR引脚用于仿真外部协处理器80387的ERROR引脚,因此通常连接到中断控制器输入请求引脚上。NE标志、IGNNE引脚和FERR引脚用于利用外部逻辑来实现PC形式的外部错误报告机制。
WP 16 (Write Protect)写保护,当关闭时PTE的只读是无效的
AM 18 (Alignment Mask)对齐,如果elfag.AC & this= 1触发强制对齐
NW 29 (Not Write-through)不直写,当NW和CD标志清除时,回写(Pentium 4,Intel Xeon,P6系列和奔腾处理器),或直写(对于Intel486处理器)
CD 30 Cache Disable禁用缓存 CD=1禁用缓存 CD=0开启缓存 可用来刷新缓存
PG 31 Paging开启页保护机制

PE与PG

PE PG 环境
0 0 处理器工作在实地址模式下
1 0 处理器工作在没有开启分页机制的保护模式下
0 1 不能在没有开启段保护的时候开启页保护,会出现一个通用异常错误(13号中断)
1 1 处理器工作在开启了分页机制的保护模式下

MP、EM与TS

TS、MP和EM位用于确定浮点指令或WAIT指令是否应该产生一个设备不存在(Device Not Available,DNA)异常

EM MP TS 浮点 WAIT/FWAIT
0 0 0 执行 执行
0 0 1 #DNA异常 执行
0 1 0 执行 执行
0 1 1 #DNA异常 #DNA异常
1 0 0 #DNA异常 执行
1 0 1 #DNA异常 执行
1 1 0 #DNA异常 执行
1 1 1 #DNA异常 #DNA异常

CR2 – 缺页异常

image-20201110173855053

通过之前的学习可以知道,一个线性地址是不一定会被挂上物理页的,当去访问这个线性地址的时候,如果他没有被挂上物理页,就会产生一个缺页异常,那么CPU是怎么知道你访问的是那个页的呢?

假设是这段汇编访问了0x12345678这个线性地址:

1
mov eax,dword ptr ds:[0x12345678]

CPU会把0x12345678这个地址保存在CR2的这个寄存器中。

如果触发了缺页异常(01号中断)的时候,就会到这个CR2寄存器中把地址取出来,挂上物理页。

CR3 – 页目录表基址

image-20201110173819101

存放页目录表基址的寄存器,在《x86内核-保护模式-页》中已有详细说明。

CR4 – 分闸

image-20201110173740003

名称 说明
VME 0 (Virtual-8086 Mode Extensions)当该位置1时为虚拟8086模式
PVI 1 (Protected-Mode Virtual Interrupts)保护模式虚拟中断(启用虚拟中断的硬件支持,通常与VME位配合使用)
TSD 2 (Time Stamp Disable)时间戳禁用,当TSD标志清除时,RDTSC指令可以在任何特权级别执行;如果设置了标志,则指令只能在特权级别0下执行。时间戳计数器在特权级别0执行时,也可以使用RDMSR指令读取。
DE 3 (Debugging Extensions)调试扩展名,调试寄存器有8个(DR0~DR7),其中DR4和DR5是没有使用的,DE位置1时,使用DR4和DR5会导致在设置时生成未定义的操作码(#UD)异常。DE位置0时,处理器用DR6或DR7的别名引用寄存器DR4和DR5,以与为在早期IA-32处理器上运行而编写的软件兼容。
PSE 4 (Page Size Extensions)页面大小扩展,PSE=1时启用具有32位分页的4MB页(可以有大页);PSE=0时,32位分页只有4k的页面(只能有小页)。
PAE 5 (Physical Address Extension)物理地址扩展,设置后,启用分页以生成物理地址超过32位(29912分页)。清除时,将物理地址限制为32位(101012分页)。
MCE 6 (Machine-Check Enable)机器检查启用,设置时启用机器检查异常(多个一个12号中断)。
PGE 7 (Page Global Enable)页面全局启用,这个位置1时,页的属性G位才能生效,已经在上一篇文章《x86内核-保护模式-页》中的TLB小节进行测试。
PCE 8 (Performance-Monitoring Counter Enable)性能监视计数器启用,在设置时,任何权限下使用RDPMC指令;清除时RDPMC指令仅可以在0级保护下执行。
OSFXSR 9 (Operating System Support for FXSAVE and FXRSTOR instructions)置1操作系统支持FXSAVE和FXRSTOR指令。
OSXMMEXCPT 10 (Operating System Support for Unmasked SIMD Floating-Point Exceptions)操作系统支持未屏蔽SIMD浮点异常,设置时,表示操作系统支持处理未绑定SIMD浮点当SIMD浮点异常(#XM)为时调用的异常处理程序的异常生成。SIMD浮点异常仅由SSE/SSE2/SSE3/SSE4.1 SIMD浮点指令生成。操作系统或执行人员必须显式设置此标志。如果未设置此标志,处理器将每当检测到未屏蔽SIMD浮点异常时,生成无效的操作码异常(#UD)。
UMIP 11 (User-Mode Instruction Prevention)用户模式指令预防,设置后,以下指令不能当CPL>0时执行:SGDT、SIDT、SLDT、SMSW和STR。尝试执行此操作会导致generalprotection异常(#GP)。
VMXE 13 (VMX-Enable Bit)VMX启用位,设置时启用VMX操作。
SMXE 14 (SMX-Enable Bit)SMX启用位,在设置时启用SMX操作(上帝模式)。
FSGSBASE 16 (FSGSBASE-Enable Bit)FSGSBASE启用位,启用指令RDFSBASE、RDGSBASE、WRFSBASE和WRGSBASE。
PCIDE 17 (PCID-Enable Bit)PCID启用位,设置时启用进程上下文标识符(PCID)。win10的1809版本之后出现了页表隔离,一个进程R0和R3分别拥有一个CR3(UserDirectoryTableBase和DirectoryTableBase),这时就出现了一个问题,CR3切换时TLB也会切换,本来TLB就经常切换了,现在还在一个进程里弄两个CR3,那TLB存在的意义就不大了,为了解决这个问题,就使用PCID来保存同一个进程的缓存。
OSXSAVE 18 (XSAVE and Processor Extended States-Enable Bit)XSAVE和Processor Extended States启用位,设置时,此标志:(1)表示(通过CPUID.01H:ECX.OSX保存[位27]),操作系统支持使用XGETBV,XSAVE和XRSTOR指令由通用软件实现;(2)使XSAVE和XRSTOR指令能够保存并恢复x87 FPU状态(包括MMX寄存器)、SSE状态(XMM寄存器和MXCSR),与XCR0中启用的其他处理器扩展状态一起;(3)使处理器能够执行XGETBV和XSETBV指令来读写XCR0。
SMEP 20 (SMEP-Enable Bit)SMEP启用位,设置时启用管理器模式执行保护(SMEP)R0不能调用R3代码。
SMAP 21 (SMAP-Enable Bit)SMAP启用位,设置时启用管理模式访问保护(SMAP)R0不能读取R3数据。
PKE 22 (Protection-Key-Enable Bit)保护密钥启用位,启用IA-32e寻呼以关联每个线性地址与保护钥匙。PKRU寄存器指定用户模式是否为线性可以读取或写入具有该保护密钥的地址。该位还允许访问PKRU寄存器使用RDPKRU和WRPKRU指令。

References:

《牛逼的火哥》

《64-ia-32-architectures-software-developer-vol-3a-part-1-manual》

《Linux内核完全剖析 – 基于0.12内核》

以及OneTrainee大佬的博客