AT&T汇编语言总结
GCC,也就是GNU C Compiler for Linux,使用的是AT&T/UNIX汇编语言的语法,与我们上课学到的x86有很大不同,主要有以下几点:
源-目标的顺序
AT&T语法中操作数的顺序与Intel的相反。Intel语法中第一个操作数为目标(寄存器,内存地址),第二个操作数为源(寄存器,内存地址),而AT&T语法中以第一个操作数为源,第二个操作数为目标。
Intel:
Op-code dst src
AT&T:
Op-code src dst
寄存器名称
寄存器名称要加%前缀。例如,使用eax寄存器时,要写%eax。
立即数操作数
立即数操作数要加$前缀。Intel语法中,十六进制数需要加h后缀,而AT&T语法中需要加0x前缀。
变量加$前缀得到的是该变量的内存地址,不加则是它的值。
操作数位数
AT&T语法中,操作数的位数由opcode的最后一位决定。后缀’b’,’w’,’l’分别表示8位,16位,32位。
Intel:
mov al, byte ptr foo
AT&T:
movb foo, %al
内存寻址
Intel:
section:[base + index*scale + disp]
AT&T:
section:base(offset, index, scale)
offset和index必须为寄存器。上式表示的内存地址为 physical address=base+offset+index∗scale 。
两种语法对照
Intel Code | AT&T Code |
---|---|
mov eax, 1 | movl $1, %eax |
mov ebx, 0ffh | movl $0xff, %ebx |
int 80h | int $0x80 |
mov ebx, eax | movl %eax, %ebx |
mov eax, [ecx] | movl (%ecx), %eax |
mov eax, [ebx + 3] | movl 3(%ebx), %eax |
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 |
先写这么多。如有错误,还请指正。