From:http://www.cnblogs.com/killerlegend/p/3906502.html
Author:KillerLegend
Date:2014.8.12
Intel和AT&T汇编语法在”长相”上看起来颇为不同,这会让在已经学过Intel语法后来又碰到AT&T语法的人产生很大的迷惑,反之也是一样的,今天就说一说一些基本的不同之处.
前缀
Intel语法中寄存器没有前缀,立即数也没有前缀.AT&T的寄存器的前缀为%以及立即数的前缀为$.Intel语法的十六进制或者二进制立即数后缀分别为h,b,如果十六进制的数字中第一个数字是字母,那么值最前面要加一个0.如下:
Intex 语法 mov eax,1 mov ebx,0ffh int 80h |
AT&T 语法 movl $1,%eax movl $0xff,%ebx int $0x80 |
操作方向
Intel和AT&T的操作方向正好相反.Intel语法中,第一个操作数是目的操作数,第二个是源操作数,AT&T与此相反.显然AT&T语法更有优势,因为我们从左往右读,写也是从左往右写,这种方式是合乎常理的.打个不恰当的比喻就是,Intel让我们回到了古人的读书方法,而AT&T则是以现代人的方式读书.
例子:
Intex 语法 instr dest,source mov eax,[ecx] |
AT&T 语法 instr source,dest movl (%ecx),%eax |
内存操作
内存操作也是不同的,Intel语法中的基寄存器包含在'['和 ']'中,而AT&T则包含于'(' 和')'之中.
例子:
Intex 语法 mov eax,[ebx] mov eax,[ebx+3] |
AT&T语法 movl (%ebx),%eax movl 3(%ebx),%eax |
相对于Intel语法而言,AT&T指令若涉及到复杂的操作将会让人很难以理解,比如在Intel中类如segreg:[base+index*scale+disp]这样的语法在AT&T中就要写成%segreg:disp(base,index,scale).其中index/scale/disp/segreg都是可选的,scale和index默认都是1.segreg则取决于指令以及应用程序是运行在实模式还是保护模式中.在实模式中,segreg取决于指令,而在保护模式中,则它是不必要的.当立即数用于scale/disp时,AT&T中的立即数不应该加上符合’$’.
例子:
Intel 语法 instr foo,segreg:[base+index*scale+disp] mov eax,[ebx+20h] add eax,[ebx+ecx*2h lea eax,[ebx+ecx] sub eax,[ebx+ecx*4h-20h] |
AT&T 语法 instr %segreg:disp(base,index,scale),foo movl 0x20(%ebx),%eax addl (%ebx,%ecx,0x2),%eax leal (%ebx,%ecx),%eax subl -0x20(%ebx,%ecx,0x4),%eax |
显然, [base+index*scale+disp]比disp(base,index,scale)要直观许多.
后缀
AT&T的语法也有后缀.这个后缀指明了操作数的大小,l指long,w指word,b指byte.Intel语法对应的分别是dword ptr, word ptr, byte ptr,dword就对应于long.
例子:
Intel 语法 mov al,bl mov ax,bx mov eax,ebx mov eax, dword ptr [ebx] |
AT&T语法 movb %bl,%al movw %bx,%ax movl %ebx,%eax movl (%ebx),%eax |