操作数赋值方向
在intel语法中,第一个操作数表示目的操作数,第二个操作数表示源操作数,赋值方向从右向左。而在AT&T语法中,第一个操作数表示源操作数,第二个操作数表示目的操作数,赋值方向从左到右。
例:将ebx赋值给eax
intel | at&t |
---|---|
mov eax,ebx | movl %ebx,%eax |
指令前缀
在intel语法中寄存器和立即数不需要前缀,而AT&T语法中寄存器需要加前缀%
,立即数需要加前缀$
Intel与AT&T前缀的区别
intel | at&t |
---|---|
mov eax,8 | movl $8,%eax |
mov ebx,0ffffh | movl $0xffff,%ebx |
int 80h | int $0x80 |
间接寻址语法
在intel语法中偏移地址使用[]
,而在AT&T语法中偏移地址使用()
。更具体来说,Intel的指令格式是segreg:[base+index*scale+disp]
,而AT&T的格式是%segreg:disp(base,index,scale)
。其中index/scale/disp/segreg都是可选的,如果没有指定scale而制定了index,则scale的缺省值为1.
寻址语法比较例子(第一行是通用语法):
Intel语法 | AT&T语法 |
---|---|
指令 foo,segreg:[base+index*scale+disp] | %segreg:disp(base,index,scale),foo |
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
表示word-16位,b
表示byte-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 |