1985年,牙膏厂 80386-CPU问世,从 16 位怼到了 32 位。
汇编语言有一丢丢的变化:

  1. 寄存器位数扩展
  2. 分段机制改变

现在 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 中,可以是:

    • 8 位寄存器 r8:
      AH、AL、BH、BL、CH、CL、DH、DL
    • 16 位寄存器 r16:
      AX、BX、CX、DX、SI、DI、BP、SP
    • 4 个段寄存器 seg:
      CS、DS、SS、ES

      存储器寻址方式

  • 指令中给出操作数的主存地址信息(偏移地址,称之为有效地址 EA),而段地址在默认的或用段超越前缀指定的段寄存器中

  • 8086 设计了多种存储器寻址方式
  1. 直接寻址方式
  2. 寄存器间接寻址方式
  3. 寄存器相对寻址方式
  4. 基址变址寻址方式
  5. 相对基址变址寻址方式

    直接寻址

  • 有效地址在指令中直接给出
  • 默认的段地址在 DS 段寄存器,可使用段超越前缀改变

MOV AX, [2000H] ; AX←DS : [2000H]
; 指令 OPCode : A10020
MOV AX,ES : [2000H] ; AX←ES : [2000H]
; 指令 OPCode : 26A10020

寄存器间接寻址

  • 有效地址存放在基址寄存器 BX 或变址寄存器 SI、DI 中
  • 默认的段地址在 DS 段寄存器,可使用段超越前缀改变

MOV AX, [SI] ; AX←DS : [SI]

寄存器相对寻址

  • 有效地址是寄存器内容与有符号 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]