x86 架构寄存器保存程序员可见的整数、控制、状态、地址转换、调试、浮点和向量状态。 宽度和可用性取决于执行模式及启用的扩展。调用约定会为其中一部分寄存器分配软件角色, 但不会改变其架构行为。
通用寄存器和子寄存器 #
IA-32 暴露 EAX、EBX、ECX、EDX、ESI、EDI、EBP 和 ESP。x86-64 将它们扩展为 RAX 至 RSP,并增加 R8 至 R15。子寄存器命名同一架构寄存器的不同部分:
RAX为 64 位,EAX是其低 32 位,AX是低 16 位,AL和AH命名AX的低字节和高字节。- 在 64 位模式中写入 32 位目标会清除高 32 位。
- 写入 16 位或 8 位目标会保留其他位。
- REX 前缀使
SPL、BPL、SIL和DIL可用,但会阻止指令编码AH、BH、CH或DH。
RIP 是 64 位指令指针,32 位代码使用 EIP。普通 MOV 不能写入它;分支、调用、返回、异常和中断返回会改变控制流。RSP 是当前栈指针。
函数边界处的寄存器用途来自 ABI。System V AMD64 使用 RDI、RSI、RDX、RCX、R8 和 R9 传递初始整数参数,而 Microsoft x64 使用 RCX、RDX、R8 和 R9。当 ABI 和展开信息允许时,RBP 可以作为帧指针,也可以作为通用寄存器。Linux 系统调用使用另一种寄存器约定,因此不能混淆函数调用和内核入口的角色。
RFLAGS #
RFLAGS 扩展了较旧的 EFLAGS 和 FLAGS 寄存器。常见的算术状态位包括:
| 标志 | 含义 |
|---|---|
CF | 无符号进位或借位 |
PF | 结果低字节的偶校验 |
AF | 传统十进制操作的辅助进位 |
ZF | 零结果 |
SF | 结果的符号位 |
OF | 有符号溢出 |
控制和系统位包括:
DF,为字符串指令选择索引递增或递减。IF,根据特权和虚拟化规则控制可屏蔽中断的传递。TF,请求在一条指令后触发调试陷阱。IOPL,参与端口 I/O 和选定的中断控制检查。NT,在传统保护模式中记录嵌套硬件任务状态。RF、VM、AC、VIF、VIP和ID,其含义取决于模式和启用的功能。
指令定义它们写入、保留或置为未定义的标志。PUSHF/POPF、中断进入和返回操作也会应用特权限制;软件不能假设当前 CPL 下的每个可见位都能被更改。
段寄存器和隐藏描述符缓存 #
CS、SS、DS、ES、FS 和 GS 具有可见选择子和隐藏的描述符状态。在保护模式中加载选择子会获取描述符,并缓存其基址、界限、类型和访问权限。编辑描述符表不会更新已经加载的缓存。
在 64 位模式中,普通地址生成会忽略 CS、SS、DS 和 ES 的基址和界限。FS 和
GS 保留通过模型特定寄存器或受支持指令设置的 64 位基址,操作系统使用它们保存线程本地和每 CPU 数据。在架构规定的范围内,选择子和描述符规则仍然适用。
GDTR 和 IDTR 保存全局描述符表和中断描述符表的线性基址及字节界限。LDTR 和 TR 保存局部描述符表及任务状态段的选择子和缓存描述符。LGDT、LIDT、LLDT 和 LTR 会在特权检查下建立这些值。x86 保护模式和特权描述了表格式和转换。
控制和系统寄存器 #
控制寄存器配置执行和地址转换:
CR0包含保护模式、分页、写保护、缓存和选定的数值状态控制。CR2接收与页错误相关的线性地址。CR3选择分页结构根,并在启用 PCID 时可以携带进程上下文标识符。CR4在支持时启用 PAE、全局页、操作系统管理的 SIMD 状态、SMEP、SMAP 和保护密钥等架构功能。CR8在 64 位模式下控制外部中断的任务优先级阈值。
模型特定寄存器(MSR)提供其他控制,包括用于长模式和不可执行启用的 EFER、系统调用目标、FS/GS 基址、内存类型和性能监控。确切的 MSR 集合取决于模型,必须从厂商文档中发现或选择。RDMSR 和 WRMSR 是特权指令。
调试寄存器 #
DR0 至 DR3 保存线性断点地址。DR7 启用断点,并选择执行、写入或数据访问条件以及支持的长度。DR6 报告调试异常发生的原因。保留编码和通用检测行为特定于架构,因此调试器或内核必须在恢复不可信调试状态之前清理值。
软件断点会将指令字节替换为 INT3。硬件调试寄存器避免更改代码,但只提供少量槽位。调试异常会与单步执行、任务切换、虚拟化和事务执行交互。
x87、MMX、SIMD 和掩码寄存器 #
x87 浮点单元暴露一个八项寄存器栈,以及控制、状态、标签、指令指针和数据指针状态。
MMX 别名引用 x87 寄存器的低 64 位存储,这正是传统 MMX 代码在返回 x87 操作前执行
EMMS 的原因。
SSE 引入 XMM 寄存器。AVX 将其低位存储扩展到 YMM;AVX-512 将其扩展到 ZMM,
并增加 K0 至 K7 的操作掩码寄存器。架构和模式决定可见寄存器数量。写入传统 SSE
目标可以保留高位向量状态,而 VEX 和 EVEX 编码的操作会应用其规定的高位清除行为。因此,
混用这些形式可能在选定处理器上产生依赖或转换开销。
MXCSR 控制 SIMD 浮点舍入、异常屏蔽、状态和非规格化处理。操作掩码寄存器控制
AVX-512 的逐通道合并或清零。其他扩展可能增加原始浮点保存格式未表示的 tile 或其他状态。
扩展状态管理 #
FXSAVE 和 FXRSTOR 覆盖 x87、MMX、SSE 及相关控制状态。XSAVE 系列使用 XCR0、
CPUID 枚举和组件位图管理可扩展状态区域。管理态组件可以使用额外的控制和保存机制。
操作系统必须只启用能够安全初始化、保存、恢复和暴露的状态组件。用户软件在执行 AVX 或更高版本指令前,会同时检查处理器支持和操作系统启用状态。上下文切换策略可以急切保存 状态,也可以使用受支持的优化,但每个线程可见的架构状态必须保持隔离。
评论
在 GitHub 上阅读或评论(发表评论需要登录)