处理器操作主要涉及处理数据。这些数据可以存储在内存中并从中访问。但是,读取数据并将其存储到内存中会减慢处理器的速度,因为它涉及将数据请求通过控制总线发送到内存存储单元并通过同一通道获取数据的复杂过程。
为了加快处理器操作速度,处理器包括了一些称为寄存器 (Registers) 的内部内存存储位置。
寄存器存储了用于处理的数据元素,而不必访问内存。处理器芯片中内置了数量有限的寄存器。
处理器寄存器
在 IA-32 体系结构中,有10个32位和6个16位处理器寄存器。寄存器分为三类——
- 通用寄存器 (General registers),
- 控制寄存器 (Control registers),以及
- 段寄存器 (Segment registers)。
通用寄存器可进一步划分成——
- 数据寄存器 (Data registers),
- 指针寄存器 (Pointer registers),以及
- 变址寄存器 (Index registers)。
数据寄存器
四个32位数据寄存器用于算术、逻辑和其他操作。这些32位寄存器可以用三种方式——
- 完整的32位数据寄存器: EAX、EBX、ECX、EDX。
- 32位寄存器的下半部分可以用作4个16位数据寄存器: AX、BX、CX 和 DX。
- 上述4个16位寄存器的以上部分可用作8个8位数据寄存器: AH、AL、BH、BL、CH、CL、DH 和 DL。
其中一些数据寄存器在算术运算中有特定的用途。
AX 是主累加器 (primary accumulator),它用于输入/输出和大多数算术指令。例如,在乘法运算中,一个操作数根据操作数的大小存储在 EAX 或 AX 或 AL 寄存器中。
BX 是基寄存器 (base register),因为它可以用于索引寻址。
CX 是计数寄存器 (count register),因为在迭代操作中 ECX,CX 寄存器将存储循环次数。
DX 是数据寄存器 (data register),它也用于输入/输出操作。它还与 AX 寄存器一起使用,对大值进行乘和除的操作。
指针寄存器
指针寄存器为32位的 EIP、ESP 和 EBP 寄存器以及相应的16位右部分 IP、SP 和 BP。有三类指针寄存器——
- 指令指针寄存器 ((Instruction Pointer) IP) ——16位 IP 寄存器存储要执行的下一个指令的偏移地址。与 CS 寄存器 (如 CS: IP) 关联的 IP 提供了代码段中当前指令的完整地址。
- 堆栈指针寄存器 ((Stack Pointer) SP) ——16位 SP 寄存器在程序堆栈中提供偏移值。SP 与 SS 寄存器 (SS: SP) 的关系是指明了程序栈内的数据或地址的当前位置。
- 基准指针寄存器 ((Base Pointer) BP) ——16位 BP 寄存器主要有助于引用传递给子程序 (subroutine) 的参数变量 (parameter variables)。将 SS 寄存器中的地址与 BP 的偏移量结合在一起,得到参数的位置。BP 还可以结合 DI 和 SI 作为特殊寻址的基础寄存器。
变址寄存器
32位索引寄存器、ESI 和 EDI 以及它们的16位最右边的部分 SI 和 DI,用于索引寻址,有时用于加法和减法。有两组索引指针——
- 源变址寄存器(Source Index (SI)) ——它用作字符串操作的源索引。
- 目的变址寄存器(Destination Index (DI)) ——它用作字符串操作的目标索引。
控制寄存器
控制寄存器包含32位指令指针寄存器和32位标志寄存器。
许多指令涉及比较和数学计算并更改标志的状态,一些其他条件指令测试这些状态标志的值以将控制流带到其他位置。
常见的标志位是:
- 溢出标志 (Overflow Flag (OF)) ——它指示在有符号算术运算后,数据的高序位 (最左侧位) 的溢出。
- 方向标志 (Direction Flag (DF)) ——它确定移动或比较字符串数据的左右方向。当 DF 值为0时,字符串操作采用从左到右的方向;当该值设置为1时,字符串操作从右向左方向。
- 中断标志 (Interrupt Flag (IF)) ——它确定是否忽略或处理诸如键盘输入等外部中断。当值为0时,它将禁用外部中断,并在设置为1时启用中断。
- 陷阱标志 (Trap Flag (TF)) ——它允许在单步模式下设置处理器的操作。我们使用的调试程序 (DEGUG) 设置了陷阱标志,因此我们可以一次单步执行一个指令。(百度百科将该寄存器称作跟踪标志 (Trace Flag),本人认为有误,参照维基百科词条 FLAGS register)
- 符号标志 (Sign Flag (SF)) ——它显示算术运算结果的符号。此标志是根据算术运算后的数据项的符号设置的。符号由最左侧位的高阶表示。正值结果将 SF 的值清除为 0,负值结果将其设置为1。
- 零标志 (Zero Flag (ZF)) ——它指示算术或比较运算的结果。非零结果将零标志清除为 0,零结果将其设置为1。
- 辅助进位标志 (Auxiliary Carry Flag (AF)) ——在算数运算后,它存储从第3位到第4位的进位,用于专用算术。当1字节算术运算导致从第3位到第4位的进位时,将设置 AF。
- 奇偶校验标志 (Parity Flag (PF)) ——它指示从算术运算获得的结果中1位的总数。偶数1位清除奇偶校验标志为 0,奇数1位将奇偶校验标志设置为1。
- 进位标志 (Carry Flag (CF)) ——它存储从一个高阶位 (最左边) 在算术运算后的0或1的进位。它还存储 移位 (shift) 或 旋转 (rotate) 操作的最后一个位的内容。
下表为16位标志寄存器中的标志位位置:
位号: | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
段寄存器
段是在程序中定义的特定区域, 用于包含数据、代码和堆栈。有三主要部分——
- 代码段 (Code Segment) ——它包含要执行的所有指令。16位代码段寄存器 (CS 寄存器) 存储代码段的起始地址。
- 数据段 (Data Segment) ——它包含数据、常量和工作区域。16位数据段寄存器 (DS 寄存器) 存储数据段的起始地址。
- 堆栈段 (Stack Segment) ——它包含程序或子程序的数据和返回地址。它是作为 "堆栈" 数据结构实现的。堆栈段寄存器 (SS 寄存器)存储堆栈的起始地址。
除了 DS、CS 和 SS 寄存器之外,还有其他额外的分段寄存器 ES (extra segment)、FS 和 GS,为存储数据提供了额外的段。
在汇编语言中,程序需要访问内存位置。段中的所有内存位置都相对于段的起始地址。段开始于一个可被16或十六进制10平均整除的地址。因此,所有这样的内存地址中最右边的十六进制数字是0,通常不存储在段寄存器中。
段寄存器存储段的起始地址。要获取段内数据或指令的确切位置,需要偏移值 (offset value) (或位移 (displacement))。要引用段中的任何内存位置,处理器将段寄存器中的段地址与位置的偏移值组合在一起。