汇编语言x86指令编码简述


若要完全理解汇编语言操作码和操作数,就需要花些时间了解汇编指令翻译成机器语言的方法。由于 Intel 指令集使用了丰富多样的指令和寻址模式,因此这个问题相当复杂。

Intel 8086 处理器是第一个使用复杂指令集计算机(Complex Instruction Set Computer, CISC)设计的处理器。这种指令集中包含了各种各样的内存寻址、移位、算术运算、数据传送和逻辑操作。

与 RISC(精简指令集计算机,Reduced Instruction Set Computer)指令相比,Intel 指令在编码和解码方面有些复杂。

指令编码(encode)是指将汇编语言指令及其操作数转换为机器码。指令解码(decode)是指将机器指令转换为汇编语言。对 Intel 指令编码和解码的逐步解释至少将有助于唤起对 MASM 作者们辛苦工作的理解和欣赏。

指令格式

一般的 x86 机器指令格式,如下图所示。包含了一个指令前缀字节、操作码、Mod R/M 字节、伸缩索引字节(SIB)、地址位移和立即数。

x86指令格式

指令按小端顺序存放,因此前缀字节位于指令的起始地址。每条指令都有一个操作码,而其他字段则是可选的。少数指令包含了全部字段,平均来看,绝大多数指令都有 2 个或 3 个字节。

下面是对指令字段的简介:

1) 指令前缀覆盖默认操作数大小。

2) 操作码(操作代码)指定指令的特定变体。比如,按照使用的参数类型,指令 ADD 有 9 种不同的操作码。

3) Mod R/M 字段指定寻址模式和操作数。符号 “R/M” 代表的是寄存器和模式。下表列出了 Mod 字段。

Mod 位移
00 DISP=0,位移低半部分和高半部分都无定义(除非r/m = 110)
01  DISP= 位移低半部分符号扩展到 16 位,位移高半部分无定义
10 DISP= 位移高半部分和低半部分都有效
11 R/M 字段包含的是寄存器编号

下表给出了当 Mod=10b 时 16 位应用程序的 R/M 字段。

R/M 有效地址  R/M 有效地址
000  [BX+SIJ+D16 100 [SI]+D16
001 [BX+DI]+D16 101  [DI]+D16
010 [BP+SI]+D16 110 [BP]+D16
011 [BP+DIJ+D16 111 [BX]+D16

4) 伸缩索引字节(scale index byte, SIB)用于计算数组索引偏移量。

5) 地址位移字段保存了操作数的偏移量,在基址-偏移量或基址-变址-偏移量寻址模式中,该字段还可以与基址或变址寄存器相加。

6) 立即数字段保存了常量操作数。