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