1985年,牙膏厂 80386-CPU问世,从 16 位怼到了 32 位。
汇编语言有一丢丢的变化:
- 寄存器位数扩展
- 分段机制改变
现在 64 位 CPU 中运行的 32 位程序,和 80386 时的运行逻辑几乎没有差别。
寄存器的扩展
无本质变化,扩展成32位的寄存器。
80386 的 32 位数据寄存器是:
EAX EBX ECX EDX
它们的低 16 位还可以看成是 16 位寄存器
AX BX CX DX
每个 16 位寄存器,还可以分成 2 个 8 位寄存器:
AH BH CH DH
AL BL CL DL
兼容了 8086 CPU
寻址方式
找到操作数的值的保存位置,叫做寻址
例如:
8B 35 78 56 34 12 | MOV ESI, DWORD PTR DS : [0x12345678]
BE 78 56 34 12 | MOV ESI, 0x12345678
第一条指令是在内存地址为 12345678 的内存中寻找 4 字节的数据。
第二条指令操作数直接是在指令的 OPCODE 中找到数据。
操作数 | 寻址方式 | 示例 |
---|---|---|
数字 | 立即数寻址 | mov eax, 1 |
寄存器 | 寄存器寻址 | mov ecx, eax |
存储器(内存) |
直接寻址 | mov eax, dword ptr ds : [0x01500000] mov ax, word ptr ds : [0x01500000] mov bl, byte ptr ds : [0x01500000] |
寄存器间接寻址 | mov eax, dword ptr [esi] | |
寄存器相对寻址 | mov eax, dword ptr [esi + 0x0C] | |
基址变址寻址 | mov eax, dword ptr [ebx + esi] | |
相对基址变址寻址 | mov eax, dword ptr [ebx + esi + 0x0C] | |
带比例存储器寻址方式 | mov eax, dword ptr [ebx + esi*2 + 0x0C] |
立即数寻址
- 指令中的操作数直接存放在机器代码中,紧跟在操作码之后(操作数作为指令的一部分存放在操作码之后的主存单元中)
- 这种操作数被称为立即数 imm
- 它可以是 8 位数值 i8(00~FF)
- 也可以是 16 位数值 i16(0000~FFFF)
-
寄存器寻址
操作数存放在 CPU 的内部寄存器 reg 中,可以是:
指令中给出操作数的主存地址信息(偏移地址,称之为有效地址 EA),而段地址在默认的或用段超越前缀指定的段寄存器中
- 8086 设计了多种存储器寻址方式
- 有效地址在指令中直接给出
- 默认的段地址在 DS 段寄存器,可使用段超越前缀改变
MOV AX, [2000H] ; AX←DS : [2000H]
; 指令 OPCode : A10020
MOV AX,ES : [2000H] ; AX←ES : [2000H]
; 指令 OPCode : 26A10020
寄存器间接寻址
- 有效地址存放在基址寄存器 BX 或变址寄存器 SI、DI 中
- 默认的段地址在 DS 段寄存器,可使用段超越前缀改变
寄存器相对寻址
- 有效地址是寄存器内容与有符号 8 位或 16 位位移量之和,寄存器可以是 BX、BP 或 SI、DI
有效地址 = BX/BP/SI/DI + 8/16 位的位移量 - 段地址对应 BX/SI/DI 寄存器默认是 DS,对应 BP 寄存器默认是 SS,可用段超越前缀改变
- 例如:
MOV AX, [DI + 06] ; AX←DS : [DI + 06]
MOV AX, [BP + 06] ; AX←SS : [BP + 06]
基址变址寻址
- 有效地址由基址寄存器(BX 或 BP)的内容加上变址寄存器(SI 或 DI)的内容构成:
有效地址 = BX/BP + SI/DI
- 段地址对应 BX 基址寄存器默认 DS,对应 BP 基址寄存器默认是 SS,可用段超越前缀改变
- 例子:
MOV AX, [BX + SI] ; AX←DS : [BX + SI]
MOV AX, [BP + DI] ; AX←SS : [BP + DI]
MOV AX, DS : [BP + DI] ; AX←DS : [BP + DI]
相对基址变址寻址
- 有效地址是基址寄存器(BX/BP)、变址寄存器(SI/DI)与一个 8 位或 16 位的位移量之和:
有效地址 = BX/BP + SI/DI + 8/16 位位移量
- 段地址对应 BX 基址寄存器默认是 DS,对应 BP 基址寄存器默认是 SS,可用段超越前缀改变
- 例子:
MOV AX, [BX + SI + 06H] ; AX←DS : [BX + SI + 06H]