AT&T和GAS彙編區別

絕大多數 Linux 程序員以前只接觸過DOS/Windows 下的彙編語言,這些彙編代碼都是Intel 風格的。但在 Unix 和 Linux 系統中,更多采用的還是 AT&T 格式,兩者在語法格式上有着很大的不同:

 

1.在 AT&T 彙編格式中,寄存器名要加上 '%' 作爲前綴;而在 Intel 彙編格式中,寄存器名不需要加前綴。例如:

AT&T 格式

Intel 格式

pushl %eax

push eax

2.在 AT&T 彙編格式中,用 '$' 前綴表示一個立即操作數;而在 Intel 彙編格式中,立即數的表示不用帶任何前綴。例如:

AT&T 格式

Intel 格式

pushl $1

push 1

3.AT&T 和 Intel 格式中的源操作數和目標操作數的位置正好相反。在 Intel 彙編格式中,目標操作數在源操作數的左邊;而在 AT&T 彙編格式中,目標操作數在源操作數的右邊。例如:

AT&T 格式

Intel 格式

addl $1, %eax

add eax, 1

4.在 AT&T 彙編格式中,操作數的字長由操作符的最後一個字母決定,後綴'b'、'w'、'l'分別表示操作數爲字節(byte,8 比特)、字(word,16 比特)和長字(long,32比特);而在 Intel 彙編格式中,操作數的字長是用 "byte ptr" 和 "word ptr" 等前綴來表示的。例如:

AT&T 格式

Intel 格式

movb val, %al

mov al, byte ptr val

5. 在 AT&T 彙編格式中,絕對轉移和調用指令(jump/call)的操作數前要加上'*'作爲前綴,而在 Intel 格式中則不需要。

6.遠程轉移指令和遠程子調用指令的操作碼,在 AT&T 彙編格式中爲 "ljump" 和 "lcall",而在 Intel 彙編格式中則爲 "jmp far" 和 "callfar",即:

AT&T 格式

Intel 格式

ljump $section, $offset

jmp far section:offset

lcall $section, $offset

call far section:offset

與之相應的遠程返回指令則爲:

AT&T 格式

Intel 格式

lret $stack_adjust

ret far stack_adjust

7.在 AT&T 彙編格式中,內存操作數的尋址方式是

section:disp(base, index, scale)

 

而在 Intel 彙編格式中,內存操作數的尋址方式爲:

section:[base + index*scale + disp]

 

由於 Linux 工作在保護模式下,用的是 32 位線性地址,所以在計算地址時不用考慮段基址和偏移量,而是採用如下的地址計算方法:

disp + base + index * scale

 

下面是一些內存操作數的例子:

AT&T 格式

Intel 格式

movl -4(%ebp), %eax

mov eax, [ebp - 4]

movl array(, %eax, 4), %eax

mov eax, [eax*4 + array]

movw array(%ebx, %eax, 4), %cx

mov cx, [ebx + 4*eax + array]

movb $4, %fs:(%eax)

mov fs:eax, 4

發佈了77 篇原創文章 · 獲贊 14 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章