- 前缀不同
在Intel的语法中,寄存器和和立即数都没有前缀。
但是在AT&T中,寄存器前需要加上"%",而立即数前需要加上"$"。
在Intel的语法中,十六进制和二进制立即数后缀分别是"h"和"b",而在AT&T中,十六进制立即数前需要加上"0x"。
Intel语法 | AT&T语法 |
mov eax,8 | movl $8,%eax |
mov ebx,0ffffh | movl $0xffff,%ebx |
int 80h | int $0x80 |
- 操作数方向不同
Intel与AT&T操作数的方向正好相反。
在Intel语法中,第一个操作数是目的操作数,第二个操作数源操作数。
而在AT&T中,第一个数是源操作数,第二个数是目的操作数。
Intel语法 | AT&T语法 |
mov eax,[ecx] | movl (%ecx),%eax |
- 内存单元操作数不同
在Intel的语法中,基寄存器用"[]"括起来,而在AT&T中,用"()"括起来。
Intel语法 | AT&T语法 |
mov eax,[ebx+5] | movl 5(%ebx),%eax |
- 寻址方式不同
Intel的指令格式是segreg:[base+index*scale+disp],而AT&T的格式是%segreg:disp(base,index,scale)。
其中index/scale/disp/segreg全部是可选的,完全可以简化掉。
如果没有指定scale而指定了index,则scale的缺省值为1。
当立即数用在scale/disp中时,不应当在其前冠以"$"前缀。
Intel语法 | AT&T语法 |
mov eax,[ebx+20h] | movl 0x20(%ebx),%eax |
add eax,[ebx+ecx*2h | addl (%ebx,%ecx,0x2),%eax |
lea eax,[ebx+ecx] | leal (%ebx,%ecx),%eax |
sub eax,[ebx+ecx*4h-20h] | subl -0x20(%ebx,%ecx,0x4),%eax |
- 后缀不同
在AT&T的操作码后面有一个后缀,其含义就是指出操作码的大小。
"l"表示长整数(32位),"w"表示字(16位),"b"表示字节(8位)。
而在Intel的语法中,则要在内存单元操作数的前面加上byte ptr, word ptr 和 dword ptr。
Intel语法 | AT&T语法 |
mov al,bl | movb %bl,%al |
mov ax,bx | movw %bx,%ax |
mov eax,ebx | movl %ebx,%eax |
mov eax,dword ptr [ebx] | movl (%ebx),%eax |