AT&T彙編指令總結

來源:互聯網
上載者:User

1.寄存器引用
   引用寄存器要在寄存器號前加百分比符號%,如“movl %eax, %ebx”。
    80386有如下寄存器:
    8個32-bit寄存器 %eax,%ebx,%ecx,%edx,%edi,%esi,%ebp,%esp;
    8個16-bit寄存器 它們事實上是上面8個32-bit寄存器的低16位:
                   %ax,%bx,%cx,%dx,%di,%si,%bp,%sp;
    8個8-bit寄存器  %ah,%al,%bh,%bl,%ch,%cl,%dh,%dl。
                  它們事實上是寄存器%ax,%bx,%cx,%dx的高8位和低8位;
    6個段寄存器   %cs(code),%ds(data),%ss(stack), %es,%fs,%gs;
    3個控制寄存器 %cr0,%cr2,%cr3;
    6個debug寄存器  %db0,%db1,%db2,%db3,%db6,%db7;
    2個測試寄存器  %tr6,%tr7;
    8個浮點寄存器棧 %st(0),%st(1),%st(2),%st(3),%st(4),%st(5),%st(6),%st(7)。
2. 運算元順序
    運算元排列是從源(左)到目的(右),如“movl %eax(源), %ebx(目的)”
3. 立即數
    使用立即數,要在數前面加符號$
      如“movl $0x04, %ebx”
         或者:
         para = 0x04
         movl $para, %ebx
    指令執行的結果是將立即數04h裝入寄存器ebx。
4. 符號常數
    符號常數直接引用 如
    value: .long 0x12a3f2de
    movl value , %ebx
    指令執行的結果是將常數0x12a3f2de裝入寄存器ebx。
    引用符號地址在符號前加符號$, 如“movl $value, % ebx”則是將符號value的地址裝入寄存
    器ebx。
5. 運算元的長度
        運算元的長度用加在指令後的符號表示b(byte, 8-bit), w(word, 16-bits), l
    (long, 32-bits),如“movb %al, %bl”,“movw %ax, %bx”,“movl %eax, %ebx ”。
        如果沒有指定運算元長度的話,編譯器將按照目標運算元的長度來設定。比如指令“mov %
    ax, %bx”,由於目標運算元bx的長度為word,那麼編譯器將把此指令等同於“movw %ax, %
    bx”。同樣道理,指令“mov $4, %ebx”等同於指令“movl $4, %ebx”,“push %al”等同
    於“pushb %al”。對於沒有指定運算元長度,但編譯器又無法猜測的指令,編譯器將會報錯,
    比如指令“push $4”。
6. 符號擴充和零擴充指令
        絕大多數面向80386的AT&T彙編指令與Intel格式的彙編指令都是相同的,符號擴充指令和
    零擴充指令則是僅有的不同格式指令。符號擴充指令和零擴充指令需要指定源運算元長度和目的
    運算元長度,即使在某些指令中這些運算元是隱含的。
        在AT&T文法中,符號擴充和零擴充指令的格式為,基本部分"movs"和"movz"(對應Intel語
    法的movsx和movzx),後面跟上源運算元長度和目的運算元長度。movsbl意味著movs (from)
    byte (to)long;movbw意味著movs (from)byte (to)word;movswl意味著
    movs (from)word (to)long。對於movz指令也一樣。比如指令“movsbl %al, %edx”意味
    著將al寄存器的內容進行符號擴充後放置到edx寄存器中。
 
    其它的Intel格式的符號擴充指令還有:
            cbw -- sign-extend byte in %al to word in %ax;
            cwde -- sign-extend word in %ax to long in %eax;
            cwd -- sign-extend word in %ax to long in %dx:%ax;
            cdq -- sign-extend dword in %eax to quad in %edx:%eax;
    對應的AT&T文法的指令為cbtw,cwtl,cwtd,cltd。
7. 調用和跳轉指令
        段內調用和跳轉指令為"call","ret"和"jmp",段間調用和跳轉指令為   
    為:"lcall","lret"和"ljmp"。
        段間調用和跳轉指令的格式為“lcall/ljmp $SECTION, $OFFSET”,而段間返回指令則為
    “lret $STACK-ADJUST”。
8. 首碼
    作業碼首碼被用在下列的情況:
        字串重複操作指令(rep,repne);
        指定被操作的段(cs,ds,ss,es,fs,gs);
        進行匯流排加鎖(lock);
        指定地址和操作的大小(data16,addr16);
    在AT&T彙編文法中,作業碼首碼通常被單獨放在一行,後面不跟任何運算元。例如,對於重複
    scas指令,其寫法為:
             repne
             scas
    上述作業碼首碼的意義和用法如下:
        指定被操作的段首碼為cs,ds,ss,es,fs,和gs。在AT&T文法中,只需要按照
    section:memory-operand的格式就指定了相應的段首碼。比如:lcall %:realmode_swtch
    運算元/地址大小
        首碼是“data16”和"addr16",它們被用來在32-bit運算元/地址代碼中指定16-bit的操
    作數/地址。
        匯流排加鎖首碼“lock”,它是為了在多處理器環境中,保證在當前指令執行期間禁止一切中
    斷。這個首碼僅僅對ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,DEC, INC, NEG, NOT,
    OR, SBB, SUB, XOR, XADD,XCHG指令有效,如果將Lock首碼用在其它指令之前,將會引起異
    常。
        字串重複操作首碼"rep","repe","repne"用來讓字串操作重複“%ecx”次。
9. 記憶體引用
    Intel文法的間接記憶體引用的格式為:
        section:[base+index*scale+displacement]
    而在AT&T文法中對應的形式為:
        section:displacement(base,index,scale)
    其中,base和index是任意的32-bit base和index寄存器。scale可以取值1,2,4,8。如果不
    指定scale值,則預設值為1。section可以指定任意的段寄存器作為段首碼,預設的段寄存器在
    不同的情況下不一樣。如果你在指令中指定了預設的段首碼,則編譯器在目標代碼中不會產生此
    段首碼代碼。
如果call和jump操作在運算元前指定首碼“*”,則表示是一個絕對位址調用/跳轉,也就是說jmp/call指令指定的是一個絕對位址。如果沒有指定"*",則運算元是一個相對位址。
任何指令如果其運算元是一個記憶體操作,則指令必須指定它的操作尺寸(byte,word,long),也就是說必須帶有指令尾碼(b,w,l)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.