处理器操作主要涉及处理数据。 该数据可以存储在存储器中并从其访问。 然而,从存储器中读取数据并将数据存储到存储器中会减慢处理器的速度,因为它涉及到通过控制总线发送数据请求并进入存储器存储单元并通过同一通道获取数据的复杂过程。
为了加快处理器的运行,处理器包括一些内部存储器的存储位置,称为寄存器(Register)。
寄存器存储要处理的数据元素,而不必访问存储器。 处理器芯片中内置了数量有限的寄存器。
处理器寄存器
IA-32体系结构中有10个32位和6个16位处理器寄存器。 寄存器分为三类
- 通用寄存器
- 控制寄存器
- 段寄存器
而通用寄存器进一步可以分为以下几类
- 数据寄存器
- 指针寄存器
- 索引寄存器
数据寄存器
四个32位数据寄存器用于算术,逻辑和其他运算。 这些32位寄存器可以三种方式使用
- 作为完整的32位数据寄存器:EAX,EBX,ECX,EDX。
- 下半部分的32位寄存器可用作四个16位数据寄存器:AX,BX,CX和DX。
- 上述四个16位寄存器的下半部分和上半部分可以用作八个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组合用作特殊寻址的基址寄存器。
大概就长这样,SP和BP, 不要记成SB了!
索引寄存器
32位索引寄存器ESI和EDI及其最右边的16位部分。 SI和DI用于索引寻址,有时用于加法和减法。 有两组索引指针
- 源索引(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位标志寄存器中标志位的位置
也就是说,所有的标志位都在一个2个字节大小的寄存器(CF, 不是打游戏的那个)中。
段寄存器
段是程序中定义的用于包含数据,代码和堆栈的特定区域。 主要分为三个部分
- 代码段-它包含所有要执行的指令。 16位代码段寄存器或CS寄存器存储代码段的起始地址。
- 数据段-它包含数据,常量和工作区。 16位数据段寄存器或DS寄存器存储数据段的起始地址。
- 堆栈段-包含数据或过程或子例程的返回地址。 它被实现为“堆栈”数据结构。 堆栈段寄存器或SS寄存器存储堆栈的起始地址。
除DS,CS和SS寄存器外,还有其他段寄存器-ES(额外段),FS和GS,它们提供了用于存储数据的其他段。
在汇编编程中,程序需要访问存储器位置。 段中的所有存储位置都相对于段的起始地址。 段的起始地址可以是16或十六进制的整数,因此,所有此类存储地址中最右边的十六进制数字为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
*********
大家可以对照一下上一篇文章中的Hello world程序,加深一下这两节内容的理解。
关注公众号(知青语),资料和软件都在里面。