GNU为了与先前的各种UNIX版本和工具有尽可能好的兼容性,继承了AT&T的386汇编语言格式,而不采用Intel的汇编语言格式。两种格式其实大同小异。区别主要在于:在Intel格式中大多使用大写字母,寄存器不带前缀,目标码在前,源在后,在表示内存单元的操作数前加“BYTE PTR”,“WORD PTR”或“DWORD PTR”来表示。而在AT&T格式中,用小写字母,寄存器前加前缀“%”,源操作数在前,目标操作数在后。操作码的最后一个字母表示位宽,如“b”表示8位,“w”表示16位,“l”表示32位。直接操作数前加上“$”。举例如下。
Intel格式:
MOV AL, BYTE PTR FOO
CALL FAR SECTION:OFFSET
JMP FAR SECTION:OFFSET
RET FAR STACK_ADJUST
SECTION:[BASE+INDEX*SCALE+DISP]
AT&T格式:
movb FOO, %al //目标操作数:a寄存器32位宽
lcall $section, $offset //直接操作数section
ljmp $section, $offset
lret $stack_adjust
section: disp(base,index,scale)//这种寻址方式常用于数组中访问特定元素内的一个字段,base是数组起始地址,index是下标,scale是每个数组元素的大小。
下面是一些例子,给出了Intel与AT&T汇编的对比。
直接寻址:
AT&T: _booga ; _booga是一个全局的C变量
注:加上$是表示地址引用,不加是表示值引用。对于局部变量,可以通过堆栈指针引用。
Intel: [_booga]
寄存器间接寻址:
AT&T: (%eax)
Intel: [eax]
变址寻址:
AT&T: _variable(%eax)
Intel: [eax + _variable]
AT&T: _array(,%eax,4)
Intel: [eax*4 + _array]
AT&T: _array(%ebx,%eax,icon_cool.gif
Intel: [ebx + eax*8 + _array]






