4.2. 区别

汇编常用的有AT&T和Intel两种格式,其区别有下面这些。

4.2.1. 前缀

在AT&T汇编格式中,寄存器名要加上 % 作为前缀,如 pushl %eax;而在Intel汇编格式中,寄存器名不需要加前缀,如: push eax

4.2.2. 立即操作数

在AT&T汇编格式中,用 $ 前缀表示一个立即操作数,如 pushl $1 ;而在Intel汇编格式中,立即数的表示不用带任何前缀,如 push 1

4.2.3. 操作数顺序

AT&T和Intel格式中的源操作数和目标操作数的位置正好相反。在Intel汇编格式中,目标操作数在源操作数的左边,如 addl $1, %eax ;而在AT&T汇编格式中,目标操作数在源操作数的右边,如 add eax, 1

4.2.4. 字长

在AT&T汇编格式中,操作数的字长由操作符的最后一个字母决定,后缀 bwl 分别表示操作数为字节(byte,8bit)、字(word,16bit)和长字(long,32bit),如 movb val, %al ;而在Intel汇编格式中,操作数的字长是用 byte ptrword ptr 等前缀来表示的,如 mov al, byte ptr val

4.2.5. 绝对转移和调用指令

在AT&T汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上 * 作为前缀,而在Intel格式中则不需要。

4.2.6. 远程转移指令和远程子调用指令

远程转移指令和远程子调用指令的操作码,在AT&T汇编格式中为 ljumplcall ,如 ljump $section, $offset jmp far section:offset

而在Intel汇编格式中则为 jmp farcall far ,即 lcall $section, $offsetcall far section:offset

与之相应的远程返回指令则AT&T格式为 lret $stack_adjust ,Intel格式为 ret far stack_adjust

4.2.7. 寻址

AT&T 汇编格式中,内存操作数的寻址方式是 section:disp(base, index, scale) 。Intel汇编格式中,内存操作数的寻址方式为:section:[base + index*scale + disp]