在X86指令集中寄存器分为四类:通用寄存器、指令指针寄存器、段寄存器、标志寄存器。
数据寄存器 | EAX(Accumulator) 累加器,RAX可作为64位寄存器(RAX)、32位寄存器(EAX)、16位寄存器(AX)或两个8位寄存器(AH或AL)引用。该寄存器用于乘法、除法及一些调整指令。 | EBX(Base) 基址,RBX可作为RBX、EBX、BX、BH或BL寻址。该寄存器有时用于保存访问存储单元的偏移量。在80386及更高型号的CPU中,EBX也能寻址存储器数据;在64位的P4和Core2中,RBX也能寻址存储器数据。 | ECX(Count) 计数,RCX可作为RCX、ECX、CX、CH或CL寻址,它是一个通用寄存器,也可保存许多指令的计数值。在80386及更高型号的CPU中,ECX可保存访问存储器数据的偏移量;在64位的P4,RCX也可以寻址存储器数据。 用于计数的指令是重复的串指令(REP/REPE/REPNE)以及移位、循环和LOOP/LOOPD指令。 移位和循环指令用CL计数 重复的串指令用CX计数 LOOP/LOOPD指令用CX或ECX计数 LOOP指令使用64位RCX寄存器进行循环计数(在64位模式操作下) | EDX(Data) 数据,RDX可作为RDX、EDX、DX、DH或DL寻址,它是通用寄存器,用于保存乘法形成的部分结果,或者除法之前的部分被除数。在80386及更高型号的CPU中,可寻址存储器数据。 | ||
指针变址寄存器 | EBP(Base Pointer) 扩展基址,RBP可作为RBP、EBP或BP寻址,为了用于传送存储器数据,RBP指向存储单元。 | ESP(Stack Pointer)堆栈 | ESI(Source Index) 源,RSI可作为RSI、ESI或SI使用。通常为串指令寻址源数据串。同RDI一样,RSI也作为通用寄存器使用。如果它作为16位寄存器,就由SI寻址;如果作为32位寄存器,就由ESI寻址;如果作为64位寄存器,就由RSI寻址 | EDI(Destination Index) 目的, RDI可作为RDI、EDI或DI寻址,常用于寻址串指令的目的数据串 | ||
指令指针寄存器 | EIP(Instruction Pointer) 指令指针寄存器,寻址代码段存储区内的下一条指令,也可由转移指令或调用指令修改 a. 实模式下:寄存器是IP(16位) b. 保护模式下:寄存器是EIP(32位) c. 64位模式下:RIP包含40位地址总线,可用于寻址1TB平展模式地址空间 2. RSP(堆栈指针):寻址一个称为堆栈的存储区。 a. 作为16位寄存器被引用时,为SP b. 作为32位寄存器被引用时,为ESP | |||||
段寄存器 | CS(Code Segment) 代码段,保存微处理器使用的代码(程序和过程),它定义了存放代码的存储器段的起始地址 a. 实模式下:定义了一个64KB存储器段的起始地址 b. 保护模式:选择一个描述代码存储器起始地址和长度的描述符 c. 在8086 - 80286下:限制为64KB d. 在80386及更高型号的微处理器工作在保护模式下:代码段限制为4GB e. 在64位模式下,代码段寄存器仍然应用于平展模式 | DS(Data Segment) 数据段,包含程序使用的大部分数据,可以通过偏移地址或其他含有偏移地址的寄存器的内容访问数据段里的数据 a. 在8086 - 80286下:限制为64KB b. 在80386及更高型号的微处理器工作在保护模式下:代码段限制为4GB | SS(Stack Segment) 堆栈段,为堆栈定义一个存储区域。由堆栈段和堆栈指针寄存器确定堆栈段内当前的入口地址。 | ES 附加数据段,为某些串指令存放目的数据 | FS 附加数据段,在80386 - Core2微处理器中增加的段寄存器 | GS 附加数据段,在80386 - Core2微处理器中增加的段寄存器 |
标志寄存器 | FLAGS或PSW 标志寄存器 | |||||
条件标志寄存器 | OF(OverFlow Flag) 溢出 | SF(Sign Flag) 符号 | ZF(Zero Flag) 零 | AF(Auxilliary carry Flag) 辅助进位 | PF(Parity Flag) 奇偶 | CF(Carry Flag) 进位 |
控制标志寄存器 | DF(Direction Flag) 方向 | IF(Interupt Flag) 中断 | TF(Trap Flag) 陷阱 |
其中数据寄存器和指针变址寄存器寄存器在64/32/16/8中名字有所差异,如下:
64位 | 32位 | 16位 | 8位 |
rax | eax | ax | al/ah |
rbx | ebx | bx | bl/bh |
rcx | ecx | cx | cl/ch |
rdx | edx | dx | dl/dh |
rsi | esi | si | - |
rdi | edi | di | - |
rbp | ebp | bp | - |
rsp | esp | sp | - |
r8~r15 | r8d~r15d | r8w~r15w | r8b~r15b |
不同体系结构的CPU在其内部存在的寄存器的数量、类型以及名称可能会不同,比如ADM64 CPU这一种体系结构,这种CPU在其内部存在二十多个可直接被汇编语言中使用的调度器,还有几种仅在操作系统代码中才会出现,应用层的话,通常只会用到如下三个分类共19个调度器:
1. 通用寄存器。共有rax、rbx、rcx、rdx、rsi、rdi、rbp、rsp、r8、r9、r10、r11、r12、r13、r14、r15这16个寄存器,CPU对它们的用途没有做特殊规定,可以自定义其用途(其中rsp、rbp这两个寄存器有特殊用途)。
其中,rsp栈顶寄存器以及rbp栈基寄存器都和函数调用栈相关,其中rsp寄存器一般用来存放函数调用栈的栈顶在内存中的地址,rbp寄存器通常用来存放函数的栈帧在内存中的起始地址。
2. 程序计数寄存器(rip寄存器,也叫PC寄存器、IP寄存器)。用来存放下一条即将用来执行的指令的地址,它决定程序执行的流程。
rip寄存器中存储的值不是CPU正在执行的指令在内存中的地址,而是紧随其后那一条将要被执行的指令在内存中的地址。修改rip寄存器中的值这个操作是CPU自动控制的,不需要通过指令去修改,CPU对外也提供了几条间接修改rip寄存器的指令。
3· 段寄存器(fs、gs寄存器)。用来实现线程本地存储(TLS),比如ADM64 Linux下Go语言和pthread线程库都用fs存储器来实现线程的TLS(本地存储)。