以下内容源于网络资源的学习与整理,如有侵权请告知删除。
参考博客
Linux 汇编语言开发指南 Intel 格式--AT&T 格式_51CTO博客_at&t和intel汇编语法
前言
X86汇编语言有两种语法风格,即Intel汇编风格和AT&T汇编风格。其中DOS操作系统采用Intel汇编风格,而Linux内核源代码采用AT&T汇编风格。下面将简单介绍这两种风格的区别。
一、联系
Unix系统最初是为了PDP-11而开发的,曾先后被移植到VAX及68000系列的处理器,这些处理器都采用AT&T汇编风格,所以Unix源代码中的汇编部分也采用 AT&T 汇编风格。当 Unix 被移植到 i386 处理器时,为了省事也采用了 AT&T 的汇编风格,而非i386处理器所希望的Intel 汇编风格。Linux 作为 Unix 家族的一员,它的很多内容都发源于 Unix,所以 Linux 内核源代码也采用 AT&T 汇编风格。
尽管 AT&T 汇编语言与 Intel 汇编语言在语法上有一定的差异,但所基于的硬件知识是相同的,因此如果你熟悉 Intel 的语法格式,那么你也可以很容易地把它“移植“到 AT&T 来。
二、前缀
在 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 中,第一个数是源操作数,第二个数是目的操作数。
由此可以看出,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 的语法比较,AT&T 间接寻址方式可能更晦涩难懂一些。
Intel 的指令格式是:
segreg:[base+index*scale+disp]
AT&T 的指令格式是:
%segreg:disp(base,index,scale)
其中index/scale/disp/segreg 全部是可选的,完全可以简化掉。
如果没有指定 scale 而指定了index,则 scale 的缺省值为 1。
segreg 段寄存器依赖于指令以及应用程序是运行在实模式还是保护模式下。在实模式下它依赖于指令,在保护模式下segreg 是多余的。
在AT&T 中,当立即数用在 scale/disp 中时,不应当在其前冠以“$”前缀。
Intel 语法
指令 segreg:[base+index*scale+disp]
AT&T 语法
指令 %segreg:disp(base,index,scale)
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 的语法比较晦涩难懂,因为[base+index*scale+disp]一眼就可以看出其含义,而 disp(base,index,scale)则不可能做到这点。
这种寻址方式常常用在访问数组中某个特定元素内的一个字段,其中,base 为数组的起始地址,scale 为每个数组元素的大小,index 为下标。如果数组元素还是一个结构,则 disp 为具体字段在结构中的位移。
六、操作码的后缀
在 AT&T 的操作码后面有一个后缀,其含义就是指出操作码的大小。“l”表示长整数(32 位),“w”表示字(16 位),“b”表示字节(8 位)。
在 Intel 的语法中,则要在内存单元操作数的前面加上 byte ptr、 word ptr 和 dword ptr,“dword”对应“long”。
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