汇编 - 寄存器

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

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

寄存器存储数据元素以便处理必须访问内存.处理器芯片内置有限数量的寄存器.

处理器寄存器

有10个32位和6个16位处理器寄存器IA-32架构.寄存器分为三类 :

  • 通用寄存器,

  • 控制寄存器,和

  • 段寄存器.

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

  • 数据寄存器,

  • 指针寄存器,

  • 索引寄存器.

数据寄存器

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

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

  • 32位寄存器的下半部分可用作4个16位数据寄存器:AX,BX,CX和DX.

  • 上述四个16位寄存器的低半部分和高半部分可用作8个8位数据寄存器:AH,AL,BH,BL ,CH,CL,DH和DL.

数据寄存器

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

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

BX称为基址寄存器,因为它可用于索引寻址.

CX称为计数寄存器,因为ECX,CX寄存器在迭代操作中存储循环计数.

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

指针寄存器

指针寄存器为32位EIP,ESP和EBP寄存器以及相应的16位右部分IP,SP和BP.有三类指针寄存器 :

  • 指令指针(IP) :  16位IP寄存器存储下一条要执行的指令的偏移地址.与CS寄存器相关联的IP(作为CS:IP)给出代码段中当前指令的完整地址.

  • 堆栈指针( SP) :  16位SP寄存器提供程序堆栈中的偏移值.与SS寄存器(SS:SP)相关联的SP指的是程序堆栈中数据或地址的当前位置.

  • 基本指针( BP) :  16位BP寄存器主要有助于引用传递给子例程的参数变量. SS寄存器中的地址与BP中的偏移量组合以获得参数的位置. BP也可以与DI和SI组合作为特殊寻址的基址寄存器.

指针寄存器

索引寄存器

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

  • 源索引(SI) : 它用作字符串操作的源索引.

  • 目的地索引(DI) : 它被用作字符串操作的目标索引.

索引寄存器

控制寄存器

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位将奇偶校验标志清零,奇数个1位将奇偶校验标志设置为1.

  • 进位国旗(CF) : 它在算术运算之后包含来自高位(最左边)的0或1的进位.它还存储 shift rotate 操作的最后一位的内容.

下表显示了16位Flags寄存器中标志位的位置:

标记:



ODITSZ
A
P
C
位号:1514131211109876543210

段寄存器

段是特定的在包含数据,代码和堆栈的程序中定义的eas.有三个主要部分 :

  • 代码段 : 它包含要执行的所有指令. 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
*********