x86 的指令格式为:
指令包含的操作数个数可以是:0 个,1 个,2 个或 3 个。这里,为了清晰起见,省略掉标号和注释:
操作数有 3 种基本类型:
下表说明了标准操作数类型,它使用了简单的操作数符号(32 位模式下),这些符号来自 Intel 手册并进行了改编。本教程将用这些符号来描述每条指令的语法。
操作数 | 说明 |
---|---|
reg8 | 8 位通用寄存器:AH、AL、BH、BL、CH、CL、DH、DL |
reg16 | 16 位通用寄存器:AX、BX、CX、DX、SI、DI、SP、BP |
reg32 | 32 位通用寄存器:EAX、EEX、ECX、EDX、ESI、EDI、ESP、EBP |
reg | 通用寄存器 |
sreg | 16 位段寄存器:CS、DS、SS、ES、FS、GS |
imm | 8 位、16 位或 32 位立即数 |
imm8 | 8 位立即数,字节型数值 |
imm16 | 16 位立即数,字类型数值 |
imm32 | 32 位立即数,双字型数值 |
reg/mem8 | 8 位操作数,可以是 8 位通用寄存器或内存字节 |
reg/mem16 | 16 位立即数,可以是 16 位通用寄存器或内存字 |
reg/mem32 | 32 位立即数,可以是 32 位通用寄存器或内存双字 |
mem | 8位、16 位或 32 位内存操作数 |
变量名引用的是数据段内的偏移量。例如,如下变量 varl 的声明表示,该变量的大小类型为字节,值为十六进制的10:
.data
var1 BYTE 10h
可以编写指令,通过内存操作数的地址来解析(查找)这些操作数。假设 var1 的地址偏移量为 10400h。如下指令将该变量的值复制到 AL 寄存器中:
mov al var1
指令会被汇编为下面的机器指令:
A0 00010400
这条机器指令的第一个字节是操作代码(即操作码(opcode))。剩余部分是 var1 的 32 位十六进制地址。虽然编程时有可能只使用数字地址,但是如同 var1 一样的符号标号会让使用内存更加容易。
另一种表示法。一些程序员更喜欢使用下面这种直接操作数的表达方式,因为,括号意味着解析操作:
mov al, [var1]
MASM 允许这种表示法,因此只要愿意就可以在程序中使用。由于多数程序(包括 Microsoft 的程序)印刷时都没有用括号,所以,本书只在出现算术表达式时才使用这种带括号的表示法:
mov al,[var1 + 5]