[汇编]IA-32_寄存器_寻址方式

IA-32_寄存器_寻址方式

  • 首先,在学习开始之前,需要注意的是汇编不是一种语言,不同平台有不同的汇编语言对应,__ 因为汇编和操作系统平台相关 __,所以汇编语言没有移植性。对于IA-32架构平台而言,选用的是32位80386汇编语言,也就是说本教程讨论的操作系统平台是32位的,可执行文件的格式也是32位而不是64位或16位的。

IA-32

  • IA-32(Intel Architecture),英特尔体系架构,英特尔从486开始采用,也就叫X86-32架构。相较于16位操作系统,汇编语言有了如下的改变:
  1. 16位操作系统中的中断调用相当于32位操作系统中的API调用。16位操作系统中的段地址和偏移地址在32位中消失了,在32位操作系统中统一采用平坦的内存地址模式寻址。
  2. 16位操作系统中的程序运行在RING0级,也就是说普通程序和操作系统程序运行在同一个级别并且拥有最高权限,而32位操作系统中的程序一般只拥有RING3级运行权限,程序的所有操作都受到操作系统控制,若程序要获得RING0操作特权只能通过驱动程序实现。
  3. 16位操作系统的可执行文件格式和32位操作系统的可执行文件格式不同,在32位的Windows操作系统中,可执行文件的格式叫PE格式,32位的Windows操作系统运行在CPU的保护模式之上,而16位的系统则运行在CPU的实模式上。

寄存器

EAX_EBX_ECX_EDX寄存器

  • IA-32架构中一共有4个32位寄存器,用于保存临时数据,它们分别是EAX、EBX、ECX和EDX。
  • 这4个32位寄存器的通用寄存器名字前面都有一个“E”字母,含义是“Expand”扩展,这是由于在16位的时代,这4个通用寄存器的名字是AX、BX、CX和DX,到了32位后就在它们的名字前面加个“E”来区别是32位还是16位。
  • 这4个32位的通用寄存器可以当作16位使用,也可以当作8位使用。当作8位使用时,就将AX折开为AH和AL,AH中的“H”代表“high”,意思是高位的意思,AL中的“L”代表“low”,意思是地位的意思。同理,BX、CX和DX可折开为BH、BL、CH、CL、DH、DL来使用。
  • 具体关系如下:
寄存器 [31:24] [23:16] [15:8] [7:0]
EAX
AX × ×
AH × × ×
AL × × ×
  • 各寄存器功能如下:
  1. EAX称为累加器,常用于算数运算、布尔操作、逻辑操作、返回函数结果等。
  2. EBX寄存器:EBX称为基址寄存器,常用于存档内存地址。
  3. ECX寄存器:ECX称为计数寄存器,常用于存放循环语句的循环次数,字符串操作中也常用。
  4. EDX寄存器:称为数据寄存器,常常和EAX一起使用。

ESI_EDI变址寄存器

  • 变址寄存器,顾名思义,即是内存地址会变动的,也就是说变址寄存器中存放需要变动的位置的内存地址。80386架构中有两个变址寄存器,分别是ESI和EDI。
  1. ESI:ESI称为源变址寄存器,通常存放要处理的数据的内存地址。
  2. EDI:EDI称为目的变址寄存器,通常存放处理后的数据的内存地址。
  • ESI和EDI常用来配合使用完成数据的赋值操作,下面是一个ESI和EDI配合使用的例子。指令把ESI所指向的内存地址中的内容复制到EDI所指向的内存中,数据的长度在ECX寄存器中指定。
Rep movs dword ptr [edi], dword ptr [esi]

EBP_ESP_EIP指针寄存器

  • 80386的指针寄存器有基址寄存器EBP,堆栈指针寄存器ESP和指令指针寄存器EIP。只需要了解基址寄存器EBP和堆栈指针寄存器ESP即可,指令指针寄存器EIP总是指向下一条要执行的指令的地址,一般情况下无需修改EIP。
  1. EBP:EBP称为基址寄存器,可作为通用寄存器用于存放操作数,常用来代替堆栈指针访问堆栈中的数据。
  2. ESP:ESP称为堆栈指针寄存器,不可作为通用寄存器使用,ESP存放当前堆栈栈顶的地址,一般情况下,ESP和EBP联合使用来访问函数中的参数和局部变量。
  • 下面是一段常见的堆栈访问指令:
Push ebp
Mov ebp,esp
Sub esp,78
Push esi
Push edi
Cmp dword ptr [ebp+8],0

EFLAGS标志寄存器

  • 标志寄存器EFLAGS一共有32位,在这32位中大部分是保留和给编写操作系统的人用的,一般情况下只需知道32位的低16位中的8位即可。
  • 下面的图列出了标志寄存器EFLAGS中需要了解的8个位的位置。
  1. CF (Carry Flag): 进位标志,进位时置1,否则置0。
  2. PF (Parity Flag): 奇偶标志。结果操作数中1的个数为偶数时置1,否则置0。
  3. AF (Auxiliary carry Flag) :辅助进位标志,有进位时置1,否则置0。
  4. ZF (Zero Flag) :零标志,运算结构为0时ZF位位置1,否则置0。
  5. SF (Sign Flag):符号标志,结果为负时置1,否则置0。
  6. IF (Interrupt Flag) :中断标志.
  7. DF (Direction Flag):方向标志,在串处理指令中控制信息的方向。
  8. OF(Overflow Flag):溢出标志,溢出时为1,否则置0。
  • EFLAGS是实现条件判断和逻辑判断的一种机制,在汇编语言中一般不直接访问EFLAGS寄存器,而是通过指令的操作隐含访问EFLAGS寄存器,下面是一个利用EFLAGS寄存器的例子。
Cmp dword ptr [ebp+8],0   ;影响标志CF、ZF、SF、OF、AF和PF
Jz 00405898                         ; 如果ZF等于1,则跳转到00405898

寻址方式

  • 在汇编中,有多种寻址方式,具体如下:

立即(数)寻址

  • 立即(数)寻址:表示数据在指令当中,目标数据可以直接得到,通常用于赋值。
目标操作数为寄存器寻址,原操作数为立即数寻址
MOV  AL, 6                       ;(AL)=6
MOV  AX, 3064H             ;(AX)=3064

寄存器寻址

  • 寄存器寻址:表示数据存储在寄存器中,指令中的操作数表示寄存器的名字,通过寄存器的名字来找到数据,寄存器寻址也是比较快速的,也是最常用的寻址方式。
原操作数和目的操作数为寄存器寻址
MOV AL,AH   ;(AL)=(AH)
MOV AX,BX    ;(AX)=(BX)

原操作数为寄存器寻址,目的操作数为存储器寻址
MOV bvar,AL
MOV wvar,AX
MOV dvar,EAX

存储器寻址

  • 除以上两种寻址方式外,以下各种寻址方式的操作数都在存储器中,其操作数称为存储器操作数。
  • 有效地址可以由以下四种成分组成:
  1. 位移量(displacement)是存放在指令中的一个8位、16位或32位的数,它是一个地址。
  2. 基址(base)是存放在基址寄存器中的内容。通常用来指向数据段中数组或字符串的首地址。
  3. 变址(index)是存放在变址寄存器中的内容。通常用来访问数组中的某个元素或字符串中的某个字符。
  4. 比例因子(scale factor)是80386以上CPU新增加的。其值可为1、2、4或8。寻址中,可用变址寄存器的内容乘以比例因子来取得变址值。

EA=+(x)+EA=基址+(变址x比例因子)+位移量

直接寻址

  • 直接寻址:表示操作数的有效地址直接包含在指令中的寻址方式。有效地址存放在代码段的指令操作码之后,但操作数本身在存储器中,所以必须先求出操作数的物理地址。这种寻址方式常用于存取简单变量。
MOV AX,[1000H]

寄存器间接寻址

  • 寄存器间接寻址:操作数的有效地址在基址寄存器EBX、EBP或变址寄存器ESI、EDI中,而操作数在存储器中的寻址方式。对于80386及以上CPU,允许使用任何32位通用寄存器。
MOV  AL, [BX]

寄存器相对寻址

  • 寄存器相对寻址:也称为直接变址寻址方式,操作数的有效地址是一个基址(EBX、EBP)或变址(ESI、EDI)寄存器的内容和指令中给定的一个位移量(DISP)之和,有效地址由2部分组成,即:(基址<或变址>寄存器)+DISP。对于80386以上允许使用任何32位通用寄存器。
MOV  AL, 1000H[SI]

基址变址寻址

  • 基址变址寻址:操作数的有效地址是一个基址寄存器(EBX、EBP)和一个变址寄存器(ESI、EDI)的内容之和。80386以上允许使用变址部分除ESP以外的任何两个32位通用寄存器组合。缺省使用段寄存器的情况由基址寄存器决定。
MOV AL,[EBX][ESI]

相对基址变址寻址

  • 相对基址变址寻址:操作数的有效地址是一个基址和一个变址寄存器的内容和指令中给定的一个位移量之和,有效地址由三部分组成。80386以上允许使用变址部分除ESP以外的任何两个32位通用寄存器组合。缺省使用段寄存器的情况由基址寄存器决定。
MOV EAX,1000H[EBX][ESI]

变址寻址方式

  • 对于80386及以上的微处理器,提供比例寻址方式。其优点在于:对于元素大小为2、4、8字节的数组,可以在变址寄存器中给出元素下标,而由寻址方式控制直接用比例因子把下标转换为变址值。

比例变址寻址

  • 基址比例变址寻址方式:操作数是由变址寄存器和比例因子组成,计算公式如下:

EA=()EA = (变址寄存器)*比例因子

MOV ECX COUNT[ESI*4]

基址比例变址寻址

  • 基址比例变址寻址方式:操作数是由基址寄存器,变址寄存器,比例因子组成,计算公式如下:

EA=()+()EA = (基址寄存器)+(变址寄存器)*比例因子

MOV AX, [BX][SI*4]

相对基址比例变址寻址

  • 相对基址比例变址寻址:操作数是由基址寄存器,变址寄存器,比例因子和指令中给定的一个位移量组成,计算公式如下:

EA=()+()+DISPEA = (基址寄存器)+(变址寄存器)*比例因子+DISP

MOV AX, 1000H[BX][4*SI]

10总寻址方式总结

MOV  AX, 1000H              ;立即寻址方式(immediate addressing)
MOV  AX, BX                 ;寄存器寻址方式(register addressing)
MOV  AX, [1000H]            ;直接寻址方式(direct addressing)
MOV  AX, [BX]               ;寄存器间接寻址方式(register indirect addressing)
MOV  AX, 1000H[SI]          ;寄存器相对寻址方式(register relative addressing)
MOV  AX, [BX][SI]           ;基址变址寻址方式(based indexed addressing)
MOV  AX, 1000H[BX][SI]      ;相对基址变址寻址方式(relative based indexed addressing)
MOV  AX, 1000H[SI*2]        ;比例变址寻址方式(scaled indexed addressing)
MOV  AX, [BX][SI*4]         ;基址比例变址寻址方式(based scaled indexed addressing)
MOV  AX, 1000H[BX][SI*8]    ;相对基址比例变址寻址方式(relative based scaled indexed addressing)


参考:
汇编基础教程