ATT是gcc默認(rèn)的匯編格式,Microsoft采用的intel格式;
這兩種格式主要有以下不同:
1、Intel省略了大小的后綴;比如Intel是mov,ATT則是mov1
2、Intel省略了寄存器前面的%;Intel是esp,ATT是%esp
3、兩種格式描述寄存器位置的寫法不同。Intel是DWORD PTR[ebp+8],ATT是8(%ebp)
4、在有多個(gè)操作數(shù)的情況下,列出的操作數(shù)順序是相反的。
linux常用的有關(guān)匯編的基本命令
gcc -S code.c ---------------產(chǎn)生code.c文件的ATT格式匯編文件(code.s)
gcc -S -masm=intel code.c--產(chǎn)生code.c文件的Intel格式匯編文件(code.s)
如果有上面的語句產(chǎn)生的匯編格式和ATT格式一樣,則gcc沒有安裝完全
objdump -d prog-----------反匯編可執(zhí)行文件prog
Linux 平臺(tái)的標(biāo)準(zhǔn)匯編器是 GAS,它是 GCC 所依賴的后臺(tái)匯編工具,GAS 使用標(biāo)準(zhǔn)的 AT&T 匯編語法
基本用法:as -o hello.o hello.s---產(chǎn)生hello.o
ld -s -o hello hello.o---鏈接成可執(zhí)行文件
執(zhí)行 as 命令時(shí)帶上參數(shù) --gstabs 可以告訴匯編器在生成的目標(biāo)代碼中加上符號(hào)表,
同時(shí)需要注意的是,在用 ld 命令進(jìn)行鏈接時(shí)不要加上 -s 參數(shù),否則目標(biāo)代碼中的符號(hào)表在鏈接時(shí)將被刪去。
這里可以用gdb來調(diào)試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