没有操作数或只有一个隐含操作数的指令是最简单的指令。这种指令只需要操作码字段,字段值由处理器的指令集预先确定。下表列出了几个常见的单字节指令。
指令 | 操作码 | 指令 | 操作码 |
---|---|---|---|
AAA | 37 | LODSB | AC |
AAS | 3F | XLAT | D7 |
CBW | 98 | INC DX | 42 |
在这些指令中,INC DX 指令好像是不应该岀现的,它出现的原因是:指令集的设计者决定为某些常用指令提供独特的操作码。其结果是,为了代码量和执行速度要对寄存器增量操作进行优化。
立即操作数(常数)按照小端顺序(起始地址为最低字节)添加到指令。首先关注的是立即数送寄存器指令,暂不考虑内存寻址的复杂性。将一个立即字送寄存器的 MOV 指令的编码格式为:B8+rw dw,其中操作码字节的值为 B8+rw,表示将一个寄存器编号(0〜7)与 B8 相加;dw 为立即字操作数,低字节在低地址。
下表列出了操作码使用的寄存器编号。
寄存器 | 编号 | 寄存器 | 编号 |
---|---|---|---|
AX/A1 | 0 | SP/AH | 4 |
CX/CL | 1 | BP/CH | 5 |
DX/DL | 2 | SI/DH | 6 |
BX/BL | 3 | DI/BH | 7 |
下面例子中出现的所有数值都为十六进制。
【示例 1】PUSH CX 机器指令为 51。编码步骤如下:
1) 带一个 16 位寄存器操作数的 PUSH 指令编码为 50。
2) CX的寄存器编码为1,因此1+50得到操作码为51。
【示例 2】MOV AX, 1 机器指令为 B8 01 00(十六进制)。编码过程如下:
1) 立即数送 16 位寄存器的操作码为 B8。
2) AX 的寄存器编号为 0,将 0 加上 B8(参见上表所示)。
3) 立即操作数(0001)按小端顺序添加到指令(01, 00 )。
【示例 3】MOV BX, 1234h 机器指令为 BB 34 12。编码过程如下:
1) 立即数送 16 位寄存器的操作码为 B8。
2) BX 的寄存器编号为 3,将 3 加上 B8 得到操作码 BB。
3) 立即操作数字节为 34 12。
从实践的角度出发,建议手动汇编一些 MOV 立即数指令来提高能力,然后通过 MASM 的源列表文件中的生成代码来检查汇编结果。