通用寄存器(GPR)一词与专用寄存器相对。后者不能在所有情况下都使用。
从历史上看,旧的 8086 架构在其名称中引入了这种差异,直到今天:
- AX = A累加器寄存器:累加结果(**)
- BX = Base register:特定指令的基本偏移量,例如XLAT
- CX = Counter register:循环计数,例如JCXZ。
- DX = Data register:扩展数据范围,例如MUL 的结果在 DX:AX 中
- SI = S来源索引:字符串指令的来源,例如LODSB
- DI = Destination index:字符串指令的目的地,例如STOSB
- SP = Stack 指针:指向堆栈的当前项
- BP = Base指针:指向当前子程序的基址(栈帧)
(**) AX/AL 也是某种特殊用途的寄存器。许多指令具有 AX/AL 的特殊编码作为操作数,例如使用MOV 加载段寄存器。
其他特殊用途寄存器是
- 段寄存器(CS、DS、ES、SS)
- 标志寄存器 (FLAGS) 和
- 指令指针 (IP)
直到今天,这些限制中的一些限制在实模式中的 16 位指令的寻址模式中使用(参见Intel® 64 and IA-32 Architectures
Software Developer’s Manual 第 2 卷,第 2.1.5 节,表 2-1。"带 ModR/M 字节的 16 位寻址形式")
随着 32 位架构 - IA-32 的引入,整数寄存器的用途得到了普遍化,并且(几乎)每个寄存器都可以用于各种用途(因此是通用的)。这也反映在指令的寻址模式编码中,请参阅英特尔手册第 2 卷,第 2.1.5 节,表 2.2。 (比较表 2.1 和表 2.2 以了解区别)
名称的前缀分别为 E 和 R 到 EAX 和 RAX,以及它们的指示用法的历史名称现在只是常规名称。
在许多新架构中,添加了新的专用寄存器。 英特尔手册,第 1 卷,第 3.7.2 节提供了完整的概述。:
- 32 位通用寄存器(EAX、EBX、ECX、EDX、ESI、EDI、ESP 或 EBP)
- 16 位通用寄存器(AX、BX、CX、DX、SI、DI、SP 或 BP)
- 8 位通用寄存器(AH、BH、CH、DH、AL、BL、CL 或 DL)
- 段寄存器(CS、DS、SS、ES、FS 和 GS)
- EFLAGS 寄存器
- x87 FPU 寄存器(ST0 到 ST7、状态字、控制字、标签字、数据操作数指针和指令
指针)
- MMX 寄存器(MM0 到 MM7)
- XMM 寄存器(XMM0 到 XMM7)和 MXCSR 寄存器
- 控制寄存器(CR0、CR2、CR3 和 CR4)和系统表指针寄存器(GDTR、LDTR、IDTR 和任务
注册)
- 调试寄存器(DR0、DR1、DR2、DR3、DR6 和 DR7)
- MSR 寄存器
通用寄存器是一种可以用于多个目的的寄存器。这些目的是
段寄存器,例如,只能保存段值,但不能用于加法。 FPU 寄存器只能保存浮点数,不能用于寻址。
在 IA-32 中,ESP 寄存器更接近于成为 通用寄存器,因为它可以用于(几乎)所有上述目的:
- 作为值:
mov eax, esp
- 在寻址中:
mov eax, [esp+4],但 不是 像 mov eax, [4+esp*2] 这样的(缩放)索引
- 作为基础:
mov eax, [esp + eax]
- 作为计数:
inc esp 在跳转有效之前
ESP 的唯一例外是 (缩放)索引 寻址无法编码。它只能用作基址寄存器,该基址寄存器使用 SIB 字节进行特殊编码(参见英特尔手册,第 2 卷,第 2.1.5 节,表 2.3 - 参见页脚)。
为了说明ESP和其他寄存器(例如ECX)在编码上的区别:
8b 01 mov eax, [ecx] ; MOV + ModRM (normal)
8b 04 24 mov eax, [esp] ; MOV + ModRM + SIB byte
8b 41 04 mov eax, [ecx+4] ; MOV + ModRM + disp8
8b 44 24 04 mov eax, [esp+4] ; MOV + ModRM + SIB + disp8
我想尽管有这个例外,ESP 仍然可以算作一个 GPR。