ATT汇编指令总结
AT&T匯編指令總結
宗旨:技術的學習是有限的,分享的精神是無限的。
?
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)。?
總結
- 上一篇: 孪生网络图像相似度_Siamese ne
- 下一篇: zbbz插件使用教程_zbbz坐标插件