轉載地址:http://blog.csdn.net/zenny_chen/article/details/6321978
目前很多開源基於x86處理器環境的C/C++,Objective-C/C++編譯器所帶的彙編器使用AT&T格式。AT&T彙編針對x86指令集與其它處理器(比如ARM、Blackfin等)有所不同,它與Intel自訂的彙編格式有比較大的偏差。GCC的彙編器能支援Intel文法特性,可以參考我前面的博文來獲悉如何使用。不過對於最新的LLVM2.0,又開始棄用Intel文法特性了。因此不管怎麼說瞭解AT&T彙編文法還是有些好處的,呵呵。
首先,AT&T彙編在對於儲存空間訪問上,如果要指定訪問位元組的寬度,是通過加尾碼來實現的,而Intel則是在儲存空間運算元之前加訪問寬度限定詞,比如:
(Intel)mov dword ptr [edx], eax (AT&T)movl %eax, (%edx)
大部分指令對於AT&T使用以下尾碼:
b 位元組(8位),對應於Intel的byte ptr
w 字(16位),對應於Intel的word ptr
l 雙字(實際是表示long,32位),對應於Intel的dword ptr
q 四字(64位),對應於Intel的qword ptr
然而,如果是x87浮點指令的話用以下尾碼:
s 單精確度浮點(short,32位),對應於Intel的dword ptr,如果x87關於儲存訪問的指令尾碼預設,則預設為尾碼s。
l 雙精確度浮點(long,64位),對應於Intel的qword ptr。
t 擴充雙精確度浮點(twelve-byte,96位(由於四位元組對齊需要,實際精度是80位)),對應於Intel的tbyte ptr。
其次,AT&T格式中,指令後面的運算元順序與Intel格式是相反的。AT&T是源運算元在前,目的運算元在後:
(Intel)mov rax, rbx (AT&T)mov %rbx, %rax
(Intel)mov eax, cs:var (AT&T)movl %cs:var, %eax
(Intel)pinsrw xmm8, [rdi], 1 (AT&T)pinsrw $1, (%rdi), %xmm8
(Intel)pshuflw xmm8, xmm9, 0a1H (AT&T)pshuflw $0xa1, %xmm9, %xmm8
再次,AT&T與Intel文法之間的定址表示也不同:
(Intel)sub eax, [ebx + ecx * 4h - 20h] (AT&T)subl -0x20(%ebx, %ecx, 0x4), %eax
上面表示縮放因子以及位移量的立即數前不需要加$符號。
最後,AT&T與Intel之間有些指令的表示也不同:
在Intel指令表示中,如果是帶符號擴充的MOV指令是用movsx表示,而在AT&T中用movs;而Intel中零擴充MOV指令是movzx,而在AT&T中是用movz表示,比如:
(Intel)movzx rax, byte ptr [rsi + 3] (AT&T)movzb 3(%rsi), %rax
(Intel)movsx rax, word ptr [rsi + 4] (AT&T)movsw 4(%rsi), %rax
而MOVS指令在Intel指令集中是被廢棄的字串操作指令。