Intel 和AT&T 语法

时间:2022-02-04 03:20:14

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