ATT是gcc默认的汇编格式,Microsoft采用的intel格式;
这两种格式主要有以下不同:
1、Intel省略了大小的后缀;比如Intel是mov,ATT则是mov1
2、Intel省略了寄存器前面的%;Intel是esp,ATT是%esp
3、两种格式描述寄存器位置的写法不同。Intel是DWORD PTR[ebp+8],ATT是8(%ebp)
4、在有多个操作数的情况下,列出的操作数顺序是相反的。
linux常用的有关汇编的基本命令
gcc -S code.c ---------------产生code.c文件的ATT格式汇编文件(code.s)
gcc -S -masm=intel code.c--产生code.c文件的Intel格式汇编文件(code.s)
如果有上面的语句产生的汇编格式和ATT格式一样,则gcc没有安装完全
objdump -d prog-----------反汇编可执行文件prog
Linux 平台的标准汇编器是 GAS,它是 GCC 所依赖的后台汇编工具,GAS 使用标准的 AT&T 汇编语法
基本用法:as -o hello.o hello.s---产生hello.o
ld -s -o hello hello.o---链接成可执行文件
执行 as 命令时带上参数 --gstabs 可以告诉汇编器在生成的目标代码中加上符号表,
同时需要注意的是,在用 ld 命令进行链接时不要加上 -s 参数,否则目标代码中的符号表在链接时将被删去。
这里可以用gdb来调试hello
以下是ATT格式的hello的汇编代码
.file "hello.c"
.section .rodata
.LC0:
.string "Hello world!!!"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
movl $.LC0, (%esp)
call puts
movl $1, %eax
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
下面则是Intel格式hello.c的汇编代码
.file "hello.c"
.intel_syntax
.section .rodata
.LC0:
.string "Hello world!!!"
.text
.globl main
.type main, @function
main:
lea %ecx, [%esp+4]
and %esp, -16
push DWORD PTR [%ecx-4]
push %ebp
mov %ebp, %esp
push %ecx
sub %esp, 4
mov DWORD PTR [%esp], OFFSET FLAT:.LC0
call puts
mov %eax, 1
add %esp, 4
pop %ecx
pop %ebp
lea %esp, [%ecx-4]
ret