例如,INTEL 语法中基本数据移动指令的一般格式是,
mnemonic destination, source
而对于 AT&T,一般格式是
mnemonic source, destination
IA-32 架构的所有寄存器名称必须以'%' 符号为前缀,例如。 %al,%bx, %ds, %cr0 等
所有文字值必须以“$”符号为前缀。例如,
mov $100, %bx
mov $A, %al
第一条指令将值 100 移动到寄存器 AX 中,第二条指令将 ascii A 的数值移动到 AL 寄存器中。
在 AT&T 语法中,内存的引用方式如下,
segment-override:signed-offset(base,index,scale)
部分可以省略,具体取决于你想要的地址。> %es:100(%eax,%ebx,2)
请注意,偏移量和比例不应以'$'为前缀。再举几个与它们等效的 NASM 语法的例子,应该会让事情更清楚,
GAS memory operand NASM memory operand
------------------ -------------------
100 [100]
%es:100 [es:100]
(%eax) [eax]
(%eax,%ebx) [eax+ebx]
(%ecx,%ebx,2) [ecx+ebx*2]
(,%ebx,2) [ebx*2]
-10(%eax) [eax-10]
%ds:-10(%ebp) [ds:ebp-10]
Example instructions,
mov %ax, 100
mov %eax, -100(%eax)
操作数大小。有时,尤其是在将文字值移动到内存时,需要指定传输大小或操作数大小。比如指令,
mov $10, 100
仅指定将值 10 移动到内存偏移量 100,但不指定传输大小。在 NASM 中,这是通过将强制转换关键字 byte/word/dword 等添加到任何操作数来完成的。在 AT&T 语法中,这是通过在指令中添加后缀 - b/w/l - 来完成的。例如,
movb $10, %es:(%eax)
将字节值 10 移动到内存位置 [ea:eax],而
movl $10, %es:(%eax)
将长值(dword)10 移动到同一位置。
jmp、call、ret 等指令将控制权从程序的一个部分转移到另一个部分。它们可以分为到相同代码段(近)或不同代码段(远)的控制传输。可能的分支寻址类型有 - 相对偏移(标签)、寄存器、内存操作数和段偏移指针。
相对偏移量,使用标签指定,如下所示。
label1:
.
.
jmp label1
使用寄存器或内存操作数的分支寻址必须以“*”为前缀。要指定“远”控制传输,必须以“l”为前缀,如“ljmp”、“lcall”等。例如,
GAS syntax NASM syntax
========== ===========
jmp *100 jmp near [100]
call *100 call near [100]
jmp *%eax jmp near eax
jmp *%ecx call near ecx
jmp *(%eax) jmp near [eax]
call *(%ebx) call near [ebx]
ljmp *100 jmp far [100]
lcall *100 call far [100]
ljmp *(%eax) jmp far [eax]
lcall *(%ebx) call far [ebx]
ret retn
lret retf
lret $0x100 retf 0x100
段偏移指针使用以下格式指定:
jmp $segment, $offset