汇编 - 寄存器



处理器操作主要涉及数据处理。这些数据可以存储在内存中并从此处访问。但是,从内存读取数据和将数据存储到内存中会降低处理器的速度,因为它涉及通过控制总线发送数据请求到内存存储单元并通过相同通道获取数据的复杂过程。

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

寄存器存储数据元素以进行处理,而无需访问内存。处理器芯片中内置了数量有限的寄存器。

处理器寄存器

IA-32 架构中有十个 32 位和六个 16 位处理器寄存器。这些寄存器分为三类:

  • 通用寄存器,
  • 控制寄存器,以及
  • 段寄存器。

通用寄存器进一步细分为以下组:

  • 数据寄存器,
  • 指针寄存器,以及
  • 索引寄存器。

数据寄存器

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

  • 作为完整的 32 位数据寄存器:EAX、EBX、ECX、EDX。

  • 32 位寄存器的下半部分可以用作四个 16 位数据寄存器:AX、BX、CX 和 DX。

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

Data Registers

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

AX 是主累加器;它用于输入/输出和大多数算术指令。例如,在乘法运算中,一个操作数根据操作数的大小存储在 EAX 或 AX 或 AL 寄存器中。

BX 称为基址寄存器,因为它可以在索引寻址中使用。

CX 称为计数寄存器,因为 ECX、CX 寄存器在迭代运算中存储循环计数。

DX 称为数据寄存器。它也用于输入/输出操作。它也与 AX 寄存器一起用于涉及大值的乘法和除法运算。

指针寄存器

指针寄存器是 32 位 EIP、ESP 和 EBP 寄存器以及相应的 16 位右半部分 IP、SP 和 BP。指针寄存器有三种:

  • 指令指针 (IP) - 16 位 IP 寄存器存储要执行的下一条指令的偏移地址。IP 与 CS 寄存器(如 CS:IP)一起给出代码段中当前指令的完整地址。

  • 堆栈指针 (SP) - 16 位 SP 寄存器提供程序堆栈内的偏移值。SP 与 SS 寄存器(SS:SP)一起指的是程序堆栈内数据的当前位置或地址。

  • 基址指针 (BP) - 16 位 BP 寄存器主要帮助引用传递给子程序的参数变量。SS 寄存器中的地址与 BP 中的偏移量组合以获取参数的位置。BP 还可以与 DI 和 SI 结合用作基址寄存器进行特殊寻址。

Pointer Registers

索引寄存器

32 位索引寄存器 ESI 和 EDI 以及它们的 16 位最右端部分 SI 和 DI 用于索引寻址,有时也用于加法和减法。有两组索引指针:

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

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

Index Registers

控制寄存器

32 位指令指针寄存器和 32 位标志寄存器组合被认为是控制寄存器。

许多指令涉及比较和数学计算并更改标志的状态,一些其他条件指令测试这些状态标志的值以将控制流转移到其他位置。

常见的标志位是

  • 溢出标志 (OF) - 它指示带符号算术运算后数据的高位(最左位)溢出。

  • 方向标志 (DF) - 它确定移动或比较字符串数据的左右方向。当 DF 值为 0 时,字符串操作采用从左到右的方向,当值设置为 1 时,字符串操作采用从右到左的方向。

  • 中断标志 (IF) - 它确定是否忽略或处理外部中断(如键盘输入等)。当值为 0 时,它禁用外部中断,当设置为 1 时,它启用中断。

  • 陷阱标志 (TF) - 它允许将处理器的操作设置为单步模式。我们使用的 DEBUG 程序设置了陷阱标志,因此我们可以一次一步地执行指令。

  • 符号标志 (SF) - 它显示算术运算结果的符号。此标志根据算术运算后数据项的符号设置。符号由最左边的最高位指示。正结果将 SF 的值清除为 0,负结果将其设置为 1。

  • 零标志 (ZF) - 它指示算术或比较运算的结果。非零结果将零标志清除为 0,零结果将其设置为 1。

  • 辅助进位标志 (AF) - 它包含算术运算后从第 3 位到第 4 位的进位;用于专门的算术。当 1 字节算术运算导致从第 3 位到第 4 位的进位时,AF 被设置。

  • 奇偶标志 (PF) - 它指示从算术运算获得的结果中 1 位的总数。偶数个 1 位将奇偶标志清除为 0,奇数个 1 位将奇偶标志设置为 1。

  • 进位标志 (CF) - 它包含算术运算后高位(最左位)的进位 0 或 1。它还存储移位旋转操作的最后一位的内容。

下表指示标志位在 16 位标志寄存器中的位置

标志 O D I T S Z A P C
位号 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

段寄存器

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

  • 代码段 - 它包含所有要执行的指令。16 位代码段寄存器或 CS 寄存器存储代码段的起始地址。

  • 数据段 - 它包含数据、常量和工作区。16 位数据段寄存器或 DS 寄存器存储数据段的起始地址。

  • 堆栈段 - 它包含数据和过程或子程序的返回地址。它作为“堆栈”数据结构实现。堆栈段寄存器或 SS 寄存器存储堆栈的起始地址。

除了 DS、CS 和 SS 寄存器外,还有其他额外的段寄存器 - ES(额外段)、FS 和 GS,它们提供用于存储数据的其他段。

在汇编编程中,程序需要访问内存位置。段内的所有内存位置都相对于段的起始地址。段以 16 或十六进制 10 的倍数的地址开始。因此,所有此类内存地址中最右边的十六进制数字为 0,通常不存储在段寄存器中。

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

示例

查看以下简单程序以了解在汇编编程中使用寄存器。此程序在屏幕上显示 9 个星号以及一条简单消息:

section	.text
   global _start	 ;must be declared for linker (gcc)
	
_start:	         ;tell linker entry point
   mov	edx,len  ;message length
   mov	ecx,msg  ;message to write
   mov	ebx,1    ;file descriptor (stdout)
   mov	eax,4    ;system call number (sys_write)
   int	0x80     ;call kernel
	
   mov	edx,9    ;message length
   mov	ecx,s2   ;message to write
   mov	ebx,1    ;file descriptor (stdout)
   mov	eax,4    ;system call number (sys_write)
   int	0x80     ;call kernel
	
   mov	eax,1    ;system call number (sys_exit)
   int	0x80     ;call kernel
	
section	.data
msg db 'Displaying 9 stars',0xa ;a message
len equ $ - msg  ;length of message
s2 times 9 db '*'

编译并执行上述代码后,将生成以下结果:

Displaying 9 stars
*********
广告