AT&T彙編入門

來源:互聯網
上載者:User

 本文將對AT&T彙編進行簡單的介紹,如果要瞭解詳細情況,請查閱GNU as的參考手冊(http://sourceware.org/binutils/docs-2.16/as/index.html)。

剛開始接觸AT&T彙編的時候,很多人都有點犯糊塗。但是如果你有過編寫組譯工具的經驗,只要記住幾個要點,對它應該還是比較容易讓手。在以下的介紹中,我將使用NASM文法與之對照。

GNU as是GNU編譯器的一個支援(後端)程式。也許as並不適合編寫大型的組譯工具,但無論如何,它是當代unix族作業系統的一個重要組件,尤其是編寫核心時。因為它文法有點晦澀,所以,經常被人詬病,認為它不“友好”,過分地強調作為GCC的一個後端程式。如果你以前只有Intel彙編文法背景,你學習起來會稍微感到沉悶。但不管怎樣,現在很多作業系統的底層代碼就是用as彙編實現的(比如linux),如果你有興趣研究linux核心代碼的話,最好還是具備一點AT&T彙編的知識。

基本格式:
AT&T組譯工具的結構跟其它組合語言類似,由directives, labels, instructions組成,助記符最多可以跟隨三個運算元。與其它組合語言相比,最大的區別在於運算元的順序,比如Intel彙編文法的傳送指令通常是:
mnemonic destination,source
然而,在AT&T彙編中,通常是:
mnemonic source,destination
也即源運算元在左邊,目的運算元在右邊。

接下來介紹AT&T彙編在x86架構下運算元的類型:
1.寄存器
所有寄存器前面都要加首碼%。比如%al,%bx,%cr0。
move %ax,%bx
上面指令將移動寄存器ax的值到寄存器bx。
2.立即數
所有立即數必須冠以首碼$,比如:
move $100,%bx
mov $A,%al
上面第一條指令將把100放入寄存器ax中;第二條指令把A的ascii碼放入al寄存器。
3.記憶體位址
在AT&T彙編文法中,記憶體通過下面方式表達:
segment-override:sigend-offset(base,index,scale)
比如:(注意offset和scale不應該加首碼$)
 %es:100(%eax,%ebx,2)
其中某些部分在實際應用中可省略。
與NASM文法的比較:
GAS memory operand   NASM memory operand
------------------   -------------------
100     [100]
%es:100     [es:100]
(%eax)     [eax]
(%eax,%ebx)    [eax+ebx]
(%ecx,%ebx,2)    [ecx+ebx*2]
(,%ebx,2)    [ebx*2]
-10(%eax)    [eax-10]
%ds:-10(%ebp)    [ds:ebp-10]
樣本:
move %ax,100
mov %eax,-100(%eax)
上面第一條指令移動ax寄存器內容到記憶體位址100處;第二條指令一定eax寄存器內容到eax值-100的記憶體位址。

運算元大小:
經常,尤其是把立即數寫入記憶體時,需要指定運算元的“尺寸”。比如:
mov $10,100
這個資訊是不完整的,是把整數10寫到地址開始為100的一個位元組呢還是一個字?在NASM中,通過轉換關鍵字byte/word/dword 來指定該“尺寸”。在AT&T彙編中,通過對操作指令添加b/w/l等尾碼來指示運算元“尺寸”。比如:
movb  $10,%es:(%eax) #寫入一個位元組
movl  $10,%es:(%eax) #寫入一個雙字
其餘一些例子:
movl  $100, %ebx
pushl  %eax
popw  %ax

控制轉移指令:
jmp, call, ret這些指令用於控製程序從某條指令跳到另外的指令處。它又分為近跳轉(在同一段內)和遠跳轉(不同段內)。跳轉地址可以用相對位移(label),寄存器,記憶體運算元,Segment-offset指標表示:
1.相對位移(label)
label1:
...
jmp label1
2.寄存器或記憶體運算元
必須添加首碼*。如果是遠跳轉,還要對跳轉指令加上l首碼,例子:
GAS syntax   NASM syntax
==========   ===========
jmp *100   jmp  near [100]
call *100   call near [100]
jmp *%eax   jmp  near eax
jmp *%ecx   call near ecx
jmp *(%eax)   jmp  near [eax]
call *(%ebx)   call near [ebx]
ljmp *100   jmp  far  [100]
lcall *100   call far  [100]
ljmp *(%eax)   jmp  far  [eax]
lcall *(%ebx)   call far  [ebx]
ret    retn
lret    retf
lret $0x100   retf 0x100
3.Segment-offset
形如:
jmp  $segment, $offset
樣本:
jmp $0x10, $0x100000

這些就是AT&T彙編最基本的東西,應該很容易。把上面這些牢記在心中,看懂GAS的彙編代碼不是太難。如果想閱覽linux核心底層源碼的話,再瞭解一下GCC內嵌彙編格式,就可以開始了~~

 

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.