跳转至

操作数语法

虽然有些指令是完整命令,但绝大多数指令后面必须跟操作数(参数)。清单 4-6 中的每个命令至少有一个操作数,比如 EBX、EAX 和 label1。

汇编操作数有三种形式:

(cid:127)立即值:内联声明的整数值(十六进制值有尾随的 h)。

(cid:127)寄存器:引用处理器寄存器的名称。

(cid:127)内存偏移量:用括号包裹的表达式,表示某个值的内存位置。

表达式可以是立即值或寄存器。也可以是寄存器与立即值的

和或差(比如 [REG+Ah] 或 [REG-10h])。

x86 汇编中的每条指令可以有零到三个操作数,用逗号分隔多个操作数。大多数情况下,需要两个操作数的指令有一个源操作数和一个目标操作数。这些操作数的顺序取决于汇编语法。例如,清单 4-7 展示了一组用 Intel 语法编写的伪命令,Windows(以及 Windows 游戏黑客)使用这种语法:

MOV R1, 1 ; 把 R1(寄存器)设为 1(立即值)
 MOV R1, [BADF00Dh] ; 把 R1 设为 [BADFOODh] 处的值(内

存偏移量)把 R1 设为 [R2+10h] 处的值(内存偏移量)

MOV R1, [R2-20h] ; 把 R1 设为 [R2-20h] 处的值(内存偏移量)

清单 4-7:演示 Intel 语法

在 Intel 语法中,目标操作数在前,源操作数在后,所以在①处,R1 是目标,[BADFOODh] 是源。另一方面,像 GCC(可以用来在 Windows 上写机器人)这样的编译器使用叫做 AT&T; (或 UNIX)的语法。这种语法做法略有不同,如以下示例所示:

MOV $1, %R1 ; 把 R1(寄存器)设为 1(立即值)
MOV 0xBADF00D, %R1 ; 把 R1 设为 0xBADFOOD 处的值(内存偏

移量)

MOV 0x10(%R2), %R1 ; 把 R1 设为 0x10(%R2) 处的值(内存偏移

量)

MOV -0x20(%R2), %R1 ; 把 R1 设为 -0x20(%R2) 处的值(内存偏

移量)

这段代码是清单 4-7 的 AT&T; 版本。AT&T; 语法不仅反转操作数顺序,还要求操作数加前缀,并且内存偏移量操作数有不同的格式。