汇编语言 寄存器

处理器操作主要涉及处理数据。这些数据可以存储在内存中并从内存中访问。然而,从存储器中读取数据并将数据存储到存储器中会减慢处理器的速度,因为它涉及复杂的过程,即通过控制总线将数据请求发送到存储器存储单元,然后通过同一通道获取数据。

为了加速处理器的操作,处理器包括一些内部内存存储位置,称为 寄存器

寄存器 存储用于处理的数据元素,而无需访问内存。处理器芯片内置有限数量的寄存器。


处理器寄存器

IA-32 体系结构中有 10 个 32 位和 6 个 16 位处理器寄存器。

存器分为三类:

  • 通用寄存器
  • 控制寄存器
  • 段寄存器

通用寄存器进一步分为以下几类:

  • 数据寄存器
  • 指针寄存器
  • 索引寄存器
  • 数据寄存器

数据寄存器

432 位数据寄存器用于算术、逻辑和其他操作。这些 32 位寄存器可以用 3 种方式使用:

  • 作为完整的 32 位数据寄存器:EAXEBXECXEDX
  • 32 位寄存器的下半部分可以用作 4 个 16 位数据寄存器:AXBXCXDX
  • 上述四个 16 位寄存器的下半部和上半部可以用作八个 8 位数据寄存器:AH、AL、BH、BL、CH、CL、DH和DL。

其中一些数据寄存器在算术运算中有特定用途。

  • AX 是主要的累加器; 它用于输入/输出和大多数算术指令。例如,在乘法运算中,根据操作数的大小,将一个操作数存储在 EAXAXAL 寄存器中。
  • BX 称为基址寄存器,因为它可以用于索引寻址。
  • CX 称为计数寄存器,因为 ECXCX 寄存器在迭代操作中存储循环计数。
  • DX 称为数据寄存器。它也用于输入/输出操作。它还与 AX 寄存器以及 DX 一起使用,用于涉及大数值的乘法和除法运算。

指针寄存器

指针寄存器是 32 位 EIPESPEBP 寄存器以及相应的 16 位右部分 IPSPBP

指针寄存器分为三类:

  • 指令指针(IP) -16 位 IP 寄存器存储要执行的下一条指令的偏移地址。与 CS 寄存器关联的 IP(作为 CS:IP)给出了代码段中当前指令的完整地址。
  • 堆栈指针(SP) -16 位 SP 寄存器提供程序堆栈内的偏移值。与 SS 寄存器(SS:SP)关联的 SP 是指程序堆栈中数据或地址的当前位置。
  • 基本指针(BP) -16 位 BP 寄存器主要帮助参考传递给子例程的参数变量。SS 寄存器中的地址与 BP 中的偏移量相结合,以获取参数的位置。BP 也可以与 DI 和 SI 组合用作特殊寻址的基址寄存器。


索引寄存器

32 位索引寄存器 ESIEDI 及其最右边的 16 位部分。SIDI 用于索引寻址,有时用于加法和减法。

索引指针分为两种:

  • 源索引(SI) -用作字符串操作的源索引。
  • 目标索引(DI) -用作字符串操作的目标索引。


控制寄存器

将 32 位指令指针寄存器和 32 位标志寄存器组合起来视为控制寄存器。许多指令涉及比较和数学计算,并更改标志的状态,而其他一些条件指令则测试这些状态标志的值,以将控制流带到其他位置。

通用标志位是:

  • 溢出标志(OF):指示有符号算术运算后数据的高阶位(最左位)的溢出。
  • 方向标记(DF):它确定向左或向右移动或比较字符串数据的方向。DF 值为 0 时,字符串操作为从左至右的方向;当 DF 值为 1 时,字符串操作为从右至左的方向。
  • 中断标志(IF):确定是否忽略或处理外部中断(例如键盘输入等)。当值为 0 时,它禁用外部中断,而当值为 1 时,它使能中断。
  • 陷阱标志(TF):允许在单步模式下设置处理器的操作。我们使用的 DEBUG 程序设置了陷阱标志,因此我们可以一次逐步执行一条指令。
  • 符号标志(SF):显示算术运算结果的符号。根据算术运算后数据项的符号设置此标志。该符号由最左位的高位指示。正结果将 SF 的值清除为 0,负结果将其设置为 1。
  • 零标志(ZF):指示算术或比较运算的结果。非零结果将零标志清零,零结果将其清零。
  • 辅助进位标志(AF):包含经过算术运算后从位 3 到位 4 的进位;用于专业算术。当1字节算术运算引起从第 3 位到第 4 位的进位时,将设置 AF
  • 奇偶校验标志(PF):指示从算术运算获得的结果中 1 位的总数。偶数个 1 位将奇偶校验标志清为 0,奇数个 1 位将奇偶校验标志清为 1。
  • 进位标志(CF):在算术运算后,它包含一个高位(最左边)的 0 或 1 进位。它还存储移位或旋转操作的最后一位的内容。

下表列出了 16 位标志寄存器中标志位的位置:

标志ODITSZAPC
位号1514131211109876543210

段寄存器

段是程序中定义的特定区域,用于包含数据,代码和堆栈。有 3 个主要部分:

  • 代码段:它包含所有要执行的指令。16 位代码段寄存器或 CS 寄存器存储代码段的起始地址。
  • 数据段:它包含数据,常量和工作区。16 位数据段寄存器或 DS 寄存器存储数据段的起始地址。
  • 堆栈段:它包含数据或过程或子例程的返回地址。它被实现为 "堆栈" 数据结构。堆栈段寄存器或 SS 寄存器存储堆栈的起始地址。

除了 DS,CS 和 SS 寄存器外,还有其他段寄存器 - ES(额外段),FSGS,它们提供了用于存储数据的其他段。在汇编语言中,程序需要访问存储器位置。段中的所有存储位置都相对于段的起始地址。段的起始地址可以是 16 或十六进制的整数,因此,所有此类存储地址中最右边的十六进制数字为 0,通常不存储在段寄存器中。

段寄存器存储段的起始地址。为了获得数据或指令在段中的确切位置,需要一个偏移值(或位移)。为了引用段中的任何存储位置,处理器将段寄存器中的段地址与该位置的偏移值进行组合。


实例

查看以下简单程序,以了解汇编程序中寄存器的使用。

该程序在屏幕上显示 9 个星星以及一条简单消息:

  1. section .text
  2. global _start ;必须声明链接器(gcc)
  3. _start: ;告诉链接器入口点
  4. mov edx,len ;消息长度
  5. mov ecx,msg ;消息内容
  6. mov ebx,1 ;文件描述 (stdout)
  7. mov eax,4 ;系统调用编号 (sys_write)
  8. int 0x80 ;调用内核
  9. mov edx,9 ;消息长度
  10. mov ecx,s2 ;消息内容
  11. mov ebx,1 ;文件描述 (stdout)
  12. mov eax,4 ;系统调用编号 (sys_write)
  13. int 0x80 ;调用内核
  14. mov eax,1 ;系统调用编号 (sys_write)
  15. int 0x80 ;调用内核
  16. section .data
  17. msg db 'Displaying 9 stars',0xa ;消息内容
  18. len equ $ - msg ;消息长度
  19. s2 times 9 db '*'

结果如下:

  1. Displaying 9 stars
  2. *********