汇编中各寄存器的作用(16位CPU14个,32位CPU16个)和 x86汇编指令集大全(带注释)
?
From:https://www.cnblogs.com/zimmerk/articles/2520011.html
From:https://blog.csdn.net/bjbz_cxy/article/details/79467688
匯編寄存器功能詳解:https://wenku.baidu.com/view/14ef15857cd184254a353586.html
寄存器、匯編命令詳解:https://wenku.baidu.com/view/24809d8d561252d381eb6e55.html
匯編中寄存器及其用處:https://www.cnblogs.com/DismalSnail/p/8615242.html
X86CPU寄存器分析:https://blog.csdn.net/qaxzplmokn3/article/details/72518057
?
32 位 CPU 所含有的寄存器有:
? ? ? ? ? ? ? ? 4 個 數據寄存器 (EAX、EBX、ECX和EDX),又叫?通用寄存器。
? ? ? ? ? ? ? ? 2 個 變址和指針寄存器 ( ESI 和 EDI )。? ? 2 個 指針寄存器 ( ESP 和 EBP) 。
? ? ? ? ? ? ? ? 6 個 段寄存器 (ES、CS、SS、DS、FS 和 GS)。FS?和?GS?是 32位CPU?新增的,16位CPU沒有
? ? ? ? ? ? ? ? 1 個 指令指針寄存器 (EIP)。1 個 標志寄存器 (EFlags)
--------------------------------------------------
?
寄存器就好比是?CPU?身上的口袋,方便?CPU?隨時從里面拿出需要的東西來使用。
EAX: 擴展累加寄存器
EBA: 擴展基址寄存器
ECX: 擴展計數寄存器
EDX: 擴展數據寄存器
ESI: 擴展來源寄存器
EDI: 擴展目標寄存器
EBP:?擴展基址指針寄存器。
ESP:?擴展堆棧指針寄存器。棧頂指針,指向 當前堆棧 的 棧底
EIP :?擴展指令指針寄存器
?
?
?
1、數據寄存器
?
數據寄存器主要用來保存操作數和運算結果等信息,從而節省讀取操作數所需占用總線和訪問存儲器的時間。32位CPU有 4 個 32位 的通用寄存器 EAX、EBX、ECX 和 EDX。對低 16位 數據的存取,不會影響 高16位 的數據。這些低16位寄存器分別命名為:AX、BX、CX 和 DX,它和先前的 CPU 中的寄存器相一致。
4個 16 位寄存器又可分割成 8 個獨立的 8位寄存器 (AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每個寄存器都有自己的名稱,可獨立存取。程序員可利用數據寄存器的這種”可分可合”的特性,靈活地處理字/字節的信息。
- 寄存器 AX 和 AL 通常稱為累加器(Accumulator),用累加器進行的操作可能需要更少時間。累加器可用于乘、 除、輸入/輸出等操作,它們的使用頻率很高;
- 寄存器 BX 稱為 基地址寄存器(Base Register)。它可作為存儲器指針來使用;
- 寄存器 CX 稱為計數寄存器(Count Register)。在循環和字符串操作時,要用它來控制循環次數;在位操作 中,當移多位時,要用 CL 來指明移位的位數;
- 寄存器 DX 稱為數據寄存器 (Data Register)。在進行乘、除運算時,它可作為默認的操作數參與運算,也可用于存放 I/O 的端口地址。
在 16位CPU 中,AX、BX、CX 和 DX 不能作為 基址 和 變址 寄存器來存放存儲單元的地址,但在 32位 CPU中,其 32位 寄存器 EAX、EBX、ECX 和 EDX 不僅可傳送數據、暫存數據保存算術邏輯運算結果,而且也可作為指針寄存器,所以,這些32位寄存器更具有通用性。
?
?
2、變址寄存器
?
SI 存儲器指針、串指令中的源操作數指針
DI 存儲器指針、串指令中的目的操作數指針
32位CPU有2個32位通用寄存器 ESI 和 EDI。其低16位對應先前CPU中的 SI 和DI,對低16位數據的存取,不影響高16位的數據。
寄存器?ESI、EDI稱為變址寄存器(Index Register),它們主要用于存放存儲單元在段內的偏移量,用它們可實現多種存儲器操作數的尋址方式,為以不同的地址形式訪問存儲單元提供方便。
變址寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲算術邏輯運算的操作數和運算結果。
它們可作一般的存儲器指針使用。在字符串操作指令的執行過程中,對它們有特定的要求,而且還具有特殊的功能。
ESI/EDI分別叫做"源/目標索引寄存器"(source/destination index),因為?在很多字符串操作指令中,DS:ESI指向源串,而ES:EDI指向目標串。
寄存器ESI、EDI、SI 和 DI 稱為變址寄存器(Index Register),它們主要用于存放存儲單元在段內的偏移量,用它們可實現多種存儲器操作數的尋址方式,為以不同的地址形式訪問存儲單元提供方便。變址寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲算術邏輯運算的操作數和運算結果。它們可作一般的存儲器指針使用。在字符串操作指令的執行過程中,對它們有特定的要求,而且還具有特殊的功能。
?
?
3、指針寄存器
?
32位CPU有2個32位通用寄存器 EBP 和 ESP。其低16位對應先前CPU中的 BP 和 SP,對低16位數據的存取,不影響高16位的數據。
寄存器EBP、ESP、BP和SP稱為指針寄存器(Pointer Register),主要用于存放堆棧內存儲單元的偏移量,用它們可實現多種存儲器操作數的尋址方式,為以不同的地址形式訪問存儲單元提供方便。
指針寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲算術邏輯運算的操作數和運算結果。
它們主要用于訪問堆棧內的存儲單元,并且規定:
EBP、BP 為 基指針( Base Pointer ) 寄存器,用它可直接存取堆棧中的數據;
ESP、SP 為 堆棧指針(Stack Pointer) 寄存器,用它只可訪問棧頂。
?
為什么我們需要 ebp 和 esp?這2個寄存器來訪問棧?這種觀念其實來自于函數的層級調用:函數A調用函數B,函數B調用函數C,函數C調用函數D...
這種調用可能會涉及非常多的層次。編譯器需要保證在這種復雜的嵌套調用中,能夠正確地處理每個函數調用的堆棧平衡。所以我們引入了2個寄存器:
- 1. ebp 指向了本次函數調用開始時的棧頂指針,它也是本次函數調用時的 "?棧底 ",即當前函數堆棧的棧底,但是是緊鄰函數的棧頂( 這里的意思是,在一次函數調用中,ebp向下(?棧是由高地址向低地址生長?)是函數的臨時變量使用的空間 )。在函數調用開始時,我們會使用?mov ebp,esp ?把當前的 esp 保存在 ebp 中。
- 2. esp,它指向當前的棧頂,它是動態變化的,隨著我們申請更多的臨時變量,esp值不斷減小(正如前文所說,棧是向下生長的,即?棧是由 高地址 向 低地址 生長)。
- 3. 函數調用結束,我們使用?mov esp,ebp?來還原之前保存的esp。
在函數調用過程中,ebp和esp之間的空間被稱為本次函數調用的“棧幀”。函數調用結束后,處于棧幀之前的所有內容都是本次函數調用過程中分配的臨時變量,都需要被“返還”。這樣在概念上,給了函數調用一個更明顯的分界。下圖是一個程序運行的某一時刻的棧幀圖:
?
ebp 與 esp 講解
?
ebp--棧底指針,又叫?基址指針
esp--棧頂指針,又叫 堆棧指針
如圖所示,簡化后的代碼調用過程如下:
void?Layer02() {int?b = 2; }void?Layer01() {int?a = 1;Layer02(); }那么函數執行過程中ebp和esp是如何變化的呢?如下是反匯編后的代碼:
void Layer02() { 00413700 push ? ? ? ?ebp? 00413701 mov ? ? ? ? ebp,esp 00413703 sub ? ? ? ? esp,0CCh 00413709 push ? ? ? ?ebx? 0041370A push ? ? ? ?esi? 0041370B push ? ? ? ?edi? 0041370C lea ? ? ? ? edi,[ebp-0CCh] 00413712 mov ? ? ? ? ecx,33h 00413717 mov ? ? ? ? eax,0CCCCCCCCh 0041371C rep stos ? ?dword ptr es:[edi]int b = 2; 0041371E mov ? ? ? ? dword ptr [b],2 } 00413725 pop ? ? ? ? edi? 00413726 pop ? ? ? ? esi? 00413727 pop ? ? ? ? ebx? 00413728 mov ? ? ? ? esp,ebp 0041372A pop ? ? ? ? ebp? 0041372B ret我們看到函數調用開始執行如下的兩行代碼:
00413700 push ? ? ? ?ebp? 00413701 mov ? ? ? ? ebp,esp返回前執行如下代碼:
00413728 mov ? ? ? ? esp,ebp 0041372A pop ? ? ? ? ebp? 0041372B ret那么這幾行代碼到底是什么意思呢?首先,如圖上所示:
開始兩行代碼的意思是先將ebp1壓棧,然后將現在的棧頂esp1作為函數調用時的棧底,所以會執行如下語句:
那么,返回前的幾條語句又是什么意思呢?
我想大家已經猜到了,當函數調用執行結束,我們要執行相反的過程:
00413728 mov ? ? ? ? esp,ebp還原棧頂指針
0041372A pop ? ? ? ? ebp?還原棧底指針
0041372B ret返回到函數調用前的指令繼續執行。
?
通過 ollydbg 跟蹤 esp 和 ebp
ebp與esp講解:http://www.360doc.com/content/13/0309/22/9290626_270468335.shtml
調用一個函數時,先將堆棧原先的基址(EBP)入棧,以保存之前任務的信息。然后將棧頂指針的值賦給EBP,將之前的棧頂作為新的基址(棧底),然后再這個基址上開辟相應的空間用作被調用函數的堆棧。函數返回后,從EBP中可取出之前的ESP值,使棧頂恢復函數調用前的位置;再從恢復后的棧頂可彈出之前的EBP值,因為這個值在函數調用前一步被壓入堆棧。這樣,EBP和ESP就都恢復了調用前的位置,堆棧恢復函數調用前的狀態。
上幾幅圖,來說明這個調試過程更好。此文對于深刻理解ebp,esp是具有長遠意義的
可以看到,初始情況下,ebp 此時值為0012FEDC,也就是棧幀的地址,而棧頂地址 esp 值為 0012FDFC。可以看到兩個值有一定的關系。而?幀指針?的地址較高。
???? 然后我們讓它執行前兩句,push ebp,mov ebp,esp
??????? 可以看到前兩句已經執行了,那么ebp跟esp的值也發生了變化。esp=0012FDF8,ebp=0012FDF8。為神馬?一句句解讀,push ebp,向棧里面壓入了一個東西,那么棧頂此時應該發生變化了,也就是?地址-4字節。為什嗎是減法呢?因為是向低地址增長的,這點一定得注意。所以此時esp變化成了0012FDFC-4=OO12FDF8.至于ebp也等于0012FDF8就不解釋了。
?????? 接著上圖不解釋:
?? 此時呢,觀察現在的值。棧頂esp=0012FDF4,而ebp=0012FDF8;沒啥好說的,此時的棧頂已經又跑上去了,說明又有元素壓棧了。那么執行這句mov esp,ebp之后,不用說,esp跟ebp都會變成0012FDF8.我們重點看下一幅,執行完pop,讓ebp出棧,后會發生神馬。
????? 此時 ebp 已經出棧了,來看看那他們的值,esp=0012FDFC,ebp=0012FEDC.首先,ebp出棧了,這個時候棧空了,所以棧頂會變成初始時的值001212FDFC。相當于上圖中的esp=0012FDF8+4=0012FDFC.注意出棧,則棧頂+4,然后呢。ebp為啥變成了0012FEDC初始的值?ebp不是一直保存著esp的初始地址么?
?????? 所以重點就在pop這個語句了。pop ebp究竟表達神馬意思?ebp的值起初存在了棧中,出棧以后,它的值就恢復了原樣。所一句灰常重要啊。pop的意思也許就是把彈出的值賦給我們的變量,pop? ebp,也就是把存在棧中的值彈出來賦給ebp。
總結幾句:
- 1、兩句的mov ebp,esp實際上是把ebp進棧后的棧頂地址給了ebp。
- 2、在ebp沒有出棧錢,它會一直保存ebp進棧以后的棧頂值,也就是1的值。
- 3、在ebp出棧前,需要把esp恢復到只有ebp在棧中時的值。
- 4、出棧后,esp自然恢復到ebp進棧以前的初始值,而pop ebp則恢復了ebp的初始值。
- 5、pop的語義很重要,pop? ebp的意思是把當前棧頂的元素出棧,送入ebp中,而不是讓ebp出棧,這點必須明確!
?
?
?
4、段寄存器
?
段寄存器是根據內存分段的管理模式而設置的。內存單元的物理地址由段寄存器的值和一個偏移量組合而成的,這樣可用兩個較少位數的值組合成一個可訪問較大物理空間的內存地址。
CPU內部的段寄存器:
CS —— 代碼段寄存器 (Code Segment Register),其值為代碼段的段值;
DS —— 數據段寄存器 (Data Segment Register),其值為數據段的段值;
SS —— 堆棧段寄存器 (Stack Segment Register),其值為堆棧段的段值;
ES —— 附加段寄存器 (Extra Segment Register),其值為附加數據段的段值;
FS —— 附加段寄存器 (Extra Segment Register),其值為附加數據段的段值;(32位CPU新增)
GS —— 附加段寄存器 (Extra Segment Register),其值為附加數據段的段值。(32位CPU新增)
在16位CPU系統中,它只有4個段寄存器,所以,程序在任何時刻至多有4個正在使用的段可直接訪問;在32位微機系統中,它有6個段寄存器,所以,在此環境下開發的程序最多可同時訪問6個段。32位CPU有兩個不同的工作方式:實方式和保護方式。在每種方式下,段寄存器的作用是不同的。有關規定簡單描述如下:
- 實方式:?前4個段寄存器 CS、DS、ES 和 SS 與先前CPU中的所對應的段寄存器的含義完全一致,內存單元的邏輯地址仍為”段值:偏移量”的形式。為訪問某內存段內的數據,必須使用該段寄存器和存儲單元的偏移量。
- 保護方式:?在此方式下,情況要復雜得多,裝入段寄存器的不再是段值,而是稱為”選擇子”(Selector)的某個值。
?
?
5、指令指針寄存器
?
32位CPU把指令指針擴展到32位,并記作 EIP,EIP 的低16位與先前CPU中的IP作用相同。
指令指針EIP、IP(InstructionPointer)是存放下次將要執行的指令在代碼段的偏移量。在具有預取指令功能的系統中,下次要執行的指令通常已被預取到指令隊列中,除非發生轉移情況。所以,在理解它們的功能時,不考慮存在指令隊列的情況。(另一處看到的理解:EIP 返回本次調用后,下一條指令的地址。)
在實方式下,由于每個段的最大范圍為64K,所以,EIP中的高16位肯定都為0,此時,相當于只用其低16位的IP來反映程序中指令的執行次序。
?
?
6、標志寄存器
?
?
一、運算結果標志位
?
1、進位標志CF(Carry Flag)
進位標志CF主要用來反映運算是否產生進位或借位。如果運算結果的最高位產生了一個進位或借位,那么,其值為1,否則其值為0。使用該標志位的情況有:多字(字節)數的加減運算,無符號數的大小比較運算,移位操作,字(字節)之間移位,專門改變CF值的指令等。
2、奇偶標志PF(Parity Flag)
奇偶標志PF用于反映運算結果中”1″的個數的奇偶性。如果”1″的個數為偶數,則PF的值為1,否則其值為0。
利用PF可進行奇偶校驗檢查,或產生奇偶校驗位。在數據傳送過程中,為了提供傳送的可靠性,如果采用奇偶校驗的方法,就可使用該標志位。
3、輔助進位標志AF(Auxiliary Carry Flag)
在發生下列情況時,輔助進位標志AF的值被置為1,否則其值為0:
(1)、在字操作時,發生低字節向高字節進位或借位時;
(2)、在字節操作時,發生低4位向高4位進位或借位時。
對以上6個運算結果標志位,在一般編程情況下,標志位CF、ZF、SF和OF的使用頻率較高,而標志位PF和AF的使用頻率較低。
4、零標志ZF(Zero Flag)
零標志ZF用來反映運算結果是否為0。如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標志位。
5、符號標志SF(Sign Flag)
符號標志SF用來反映運算結果的符號位,它與運算結果的最高位相同。在微機系統中,有符號數采用補碼表示法,所以,SF也就反映運算結果的正負號。運算結果為正數時,SF的值為0,否則其值為1。
6、溢出標志OF(Overflow Flag)
溢出標志OF用于反映有符號數加減運算所得結果是否溢出。如果運算結果超過當前運算位數所能表示的范圍,則稱為溢出,OF的值被置為1,否則,OF的值被清為0。”溢出”和”進位”是兩個不同含義的概念,不要混淆。如果不太清楚的話,請查閱《計算機組成原理》課程中的有關章節。
?
?
二、狀態控制標志位
?
狀態控制標志位是用來控制CPU操作的,它們要通過專門的指令才能使之發生改變。
1、追蹤標志TF(Trap Flag)
當追蹤標志TF被置為1時,CPU進入單步執行方式,即每執行一條指令,產生一個單步中斷請求。這種方式主要用于程序的調試。指令系統中沒有專門的指令來改變標志位TF的值,但程序員可用其它辦法來改變其值。
2、中斷允許標志IF(Interrupt-enable Flag)
中斷允許標志IF是用來決定CPU是否響應CPU外部的可屏蔽中斷發出的中斷請求。但不管該標志為何值,CPU都必須響應CPU外部的不可屏蔽中斷所發出的中斷請求,以及CPU內部產生的中斷請求。具體規定如下:
(1)、當IF=1時,CPU可以響應CPU外部的可屏蔽中斷發出的中斷請求;
(2)、當IF=0時,CPU不響應CPU外部的可屏蔽中斷發出的中斷請求。
CPU的指令系統中也有專門的指令來改變標志位IF的值。
3、方向標志DF(Direction Flag)
方向標志DF用來決定在串操作指令執行時有關指針寄存器發生調整的方向。具體規定在第5.2.11節——字符串操作指令——中給出。在微機的指令系統中,還提供了專門的指令來改變標志位DF的值。
?
?
三、32位標志寄存器增加的標志位
?
1、I/O特權標志IOPL(I/O Privilege Level)
I/O特權標志用兩位二進制位來表示,也稱為I/O特權級字段。該字段指定了要求執行I/O指令的特權級。如果當前的特權級別在數值上小于等于IOPL的值,那么,該I/O指令可執行,否則將發生一個保護異常。
2、嵌套任務標志NT(Nested Task)
嵌套任務標志NT用來控制中斷返回指令IRET的執行。具體規定如下:
(1)、當NT=0,用堆棧中保存的值恢復EFLAGS、CS和EIP,執行常規的中斷返回操作;
(2)、當NT=1,通過任務轉換實現中斷返回。
3、重啟動標志RF(Restart Flag)
重啟動標志RF用來控制是否接受調試故障。規定:RF=0時,表示”接受”調試故障,否則拒絕之。在成功執行完一條指令后,處理機把RF置為0,當接受到一個非調試故障時,處理機就把它置為1。
4、虛擬8086方式標志VM(Virtual 8086 Mode)
如果該標志的值為1,則表示處理機處于虛擬的8086方式下的工作狀態,否則,處理機處于一般保護方式下的工作狀態。
?
?
?
一、數據傳輸指令
?
x86匯編指令詳解:https://blog.csdn.net/bekilledlzy/article/details/1765802
匯編指令速查表:https://blog.csdn.net/chenlycly/article/details/52235043
Intel匯編指令在線手冊:http://faydoc.tripod.com/cpu/index.htm
動功能匯編指令查詢器:https://www.52pojie.cn/thread-319643-1-1.html
?
數據傳送指令包括:通用數據傳送指令、地址傳送指令、標志寄存器傳送指令、符號擴展指令、擴展傳送指令等。
它們在存貯器和寄存器、寄存器和輸入輸出端口之間傳送數據.。
1. 通用數據傳送指令.?
MOV 傳送字或字節. MOVSX 先符號擴展,再傳送. MOVZX 先零擴展,再傳送. PUSH 把字壓入堆棧. POP 把字彈出堆棧. PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次壓入堆棧. POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次彈出堆棧. PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次壓入堆棧. POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次彈出堆棧. BSWAP 交換32位寄存器里字節的順序 XCHG 交換字或字節.(至少有一個操作數為寄存器,段寄存器不可作為操作數) CMPXCHG 比較并交換操作數.(第二個操作數必須為累加器AL/AX/EAX) XADD 先交換再累加.(結果在第一個操作數里) XLAT 字節查表轉換. BX指向一張256字節的表的起點,AL為表的索引值(0-255,即0-FFH);返回AL為查表結果.([BX+AL]->AL)2. 輸入輸出端口傳送指令.
IN I/O端口輸入. ( 語法: IN 累加器, {端口號│DX} ) OUT I/O端口輸出. ( 語法: OUT {端口號│DX},累加器 )輸入輸出端口由立即方式指定時, 其范圍是 0-255; 由寄存器 DX 指定時,其范圍是 0-65535.3. 目的地址傳送指令.
LEA 裝入有效地址.例: LEA DX,string ;把偏移地址存到DX. LDS 傳送目標指針,把指針內容裝入DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI. LES 傳送目標指針,把指針內容裝入ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI. LFS 傳送目標指針,把指針內容裝入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI. LGS 傳送目標指針,把指針內容裝入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI. LSS 傳送目標指針,把指針內容裝入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.4. 標志傳送指令.
LAHF 標志寄存器傳送,把標志裝入AH. SAHF 標志寄存器傳送,把AH內容裝入標志寄存器. PUSHF 標志入棧. POPF 標志出棧. PUSHD 32位標志入棧. POPD 32位標志出棧.?
?
二、算術運算指令
?
ADD 加法. ADC 帶進位加法. INC 加 1. AAA 加法的ASCII碼調整. DAA 加法的十進制調整. SUB 減法. SBB 帶借位減法. DEC 減 1. NEG 求反(以 0 減之). CMP 比較.(兩操作數作減法,僅修改標志位,不回送結果). AAS 減法的ASCII碼調整. DAS 減法的十進制調整. MUL 無符號乘法.結果回送AH和AL(字節運算),或DX和AX(字運算), IMUL 整數乘法.結果回送AH和AL(字節運算),或DX和AX(字運算), AAM 乘法的ASCII碼調整. DIV 無符號除法.結果回送:商回送AL,余數回送AH, (字節運算);或 商回送AX,余數回送DX, (字運算). IDIV 整數除法.結果回送:商回送AL,余數回送AH, (字節運算);或 商回送AX,余數回送DX, (字運算). AAD 除法的ASCII碼調整. CBW 字節轉換為字. (把AL中字節的符號擴展到AH中去) CWD 字轉換為雙字. (把AX中的字的符號擴展到DX中去) CWDE 字轉換為雙字. (把AX中的字符號擴展到EAX中去) CDQ 雙字擴展. (把EAX中的字的符號擴展到EDX中去)?
?
三、邏輯運算指令
?
AND 與運算. OR 或運算. XOR 異或運算. NOT 取反. TEST 測試.(兩操作數作與運算,僅修改標志位,不回送結果).SHL 邏輯左移. SAL 算術左移.(=SHL) SHR 邏輯右移. SAR 算術右移.(=SHR) ROL 循環左移. ROR 循環右移. RCL 通過進位的循環左移. RCR 通過進位的循環右移. 以上八種移位指令,其移位次數可達255次. 移位一次時, 可直接用操作碼. 如 SHL AX,1。 移位>1次時, 則由寄存器CL給出移位次數。如 MOV CL,04 SHL AX,CL?
?
四、串指令
?
DS:SI 源串段寄存器 :源串變址. ES:DI 目標串段寄存器:目標串變址. CX 重復次數計數器. AL/AX 掃描值. D標志 0表示重復操作中SI和DI應自動增量; 1表示應自動減量. Z標志 用來控制掃描或比較操作的結束. MOVS 串傳送. ( MOVSB 傳送字符. MOVSW 傳送字. MOVSD 傳送雙字. ) CMPS 串比較. ( CMPSB 比較字符. CMPSW 比較字. ) SCAS 串掃描. 把AL或AX的內容與目標串作比較,比較結果反映在標志位. LODS 裝入串. 把源串中的元素(字或字節)逐一裝入AL或AX中.( LODSB 傳送字符. LODSW 傳送字. LODSD 傳送雙字. ) STOS 保存串.是LODS的逆過程. REP 當CX/ECX<>0時重復. REPE/REPZ 當ZF=1或比較結果相等,且CX/ECX<>0時重復. REPNE/REPNZ 當ZF=0或比較結果不相等,且CX/ECX<>0時重復. REPC 當CF=1且CX/ECX<>0時重復. REPNC 當CF=0且CX/ECX<>0時重復.?
?
五、轉移(跳轉)指令
?
1. 無條件轉移指令 (長轉移) JMP 無條件轉移指令 CALL 過程調用 RET/RETF 過程返回. 2. 條件轉移指令 (短轉移,-128到+127的距離內)( 當且僅當(SF XOR OF)=1時,OP1<OP2 ) JA/JNBE 不小于或不等于時轉移. JAE/JNB 大于或等于轉移. JB/JNAE 小于轉移. JBE/JNA 小于或等于轉移. 以上四條,測試無符號整數運算的結果(標志C和Z). JG/JNLE 大于轉移. JGE/JNL 大于或等于轉移. JL/JNGE 小于轉移. JLE/JNG 小于或等于轉移. 以上四條,測試帶符號整數運算的結果(標志S,O和Z). JE/JZ 等于轉移. JNE/JNZ 不等于時轉移. JC 有進位時轉移. JNC 無進位時轉移. JNO 不溢出時轉移. JNP/JPO 奇偶性為奇數時轉移. JNS 符號位為 "0" 時轉移. JO 溢出轉移. JP/JPE 奇偶性為偶數時轉移. JS 符號位為 "1" 時轉移. 3. 循環控制指令(短轉移) LOOP CX不為零時循環. LOOPE/LOOPZ CX不為零且標志Z=1時循環. LOOPNE/LOOPNZ CX不為零且標志Z=0時循環. JCXZ CX為零時轉移. JECXZ ECX為零時轉移. 4. 中斷指令 INT 中斷指令 INTO 溢出中斷 IRET 中斷返回 5. 處理器控制指令 HLT 處理器暫停, 直到出現中斷或復位信號才繼續. WAIT 當芯片引線TEST為高電平時使CPU進入等待狀態. ESC 轉換到外處理器. LOCK 封鎖總線. NOP 空操作. STC 置進位標志位. CLC 清進位標志位. CMC 進位標志取反. STD 置方向標志位. CLD 清方向標志位. STI 置中斷允許位. CLI 清中斷允許位.?
?
六、偽指令
?
DW 定義字(2字節). PROC 定義過程. ENDP 過程結束. SEGMENT 定義段. ASSUME 建立段寄存器尋址. ENDS 段結束. END 程序結束.?
?
七、處理器 控制指令:標志處理指令
?
CLC 進位位置0指令 CMC 進位位求反指令 STC 進位位置為1指令 CLD 方向標志置1指令 STD 方向標志位置1指令 CLI 中斷標志置0指令 STI 中斷標志置1指令 NOP 無操作 HLT 停機 WAIT 等待 ESC 換碼 LOCK 封鎖?
?
浮點運算指令集
?
一、控制指令(帶9B的控制指令前綴F變為FN時浮點不檢查,機器碼去掉9B)FINIT 初始化浮點部件 機器碼 9B DB E3 FCLEX 清除異常 機器碼 9B DB E2 FDISI 浮點檢查禁止中斷 機器碼 9B DB E1 FENI 浮點檢查禁止中斷二 機器碼 9B DB E0 WAIT 同步CPU和FPU 機器碼 9B FWAIT 同步CPU和FPU 機器碼 D9 D0 FNOP 無操作 機器碼 DA E9 FXCH 交換ST(0)和ST(1) 機器碼 D9 C9 FXCH ST(i) 交換ST(0)和ST(i) 機器碼 D9 C1iii FSTSW ax 狀態字到ax 機器碼 9B DF E0 FSTSW word ptr mem 狀態字到mem 機器碼 9B DD mm111mmm FLDCW word ptr mem mem到狀態字 機器碼 D9 mm101mmm FSTCW word ptr mem 控制字到mem 機器碼 9B D9 mm111mmm FLDENV word ptr mem mem到全環境 機器碼 D9 mm100mmm FSTENV word ptr mem 全環境到mem 機器碼 9B D9 mm110mmm FRSTOR word ptr mem mem到FPU狀態 機器碼 DD mm100mmm FSAVE word ptr mem FPU狀態到mem 機器碼 9B DD mm110mmm FFREE ST(i) 標志ST(i)未使用 機器碼 DD C0iii FDECSTP 減少棧指針1->0 2->1 機器碼 D9 F6 FINCSTP 增加棧指針0->1 1->2 機器碼 D9 F7 FSETPM 浮點設置保護 機器碼 DB E4 二、數據傳送指令FLDZ 將0.0裝入ST(0) 機器碼 D9 EE FLD1 將1.0裝入ST(0) 機器碼 D9 E8 FLDPI 將π裝入ST(0) 機器碼 D9 EB FLDL2T 將ln10/ln2裝入ST(0) 機器碼 D9 E9 FLDL2E 將1/ln2裝入ST(0) 機器碼 D9 EA FLDLG2 將ln2/ln10裝入ST(0) 機器碼 D9 EC FLDLN2 將ln2裝入ST(0) 機器碼 D9 ED FLD real4 ptr mem 裝入mem的單精度浮點數 機器碼 D9 mm000mmm FLD real8 ptr mem 裝入mem的雙精度浮點數 機器碼 DD mm000mmm FLD real10 ptr mem 裝入mem的十字節浮點數 機器碼 DB mm101mmm FILD word ptr mem 裝入mem的二字節整數 機器碼 DF mm000mmm FILD dword ptr mem 裝入mem的四字節整數 機器碼 DB mm000mmm FILD qword ptr mem 裝入mem的八字節整數 機器碼 DF mm101mmm FBLD tbyte ptr mem 裝入mem的十字節BCD數 機器碼 DF mm100mmm FST real4 ptr mem 保存單精度浮點數到mem 機器碼 D9 mm010mmm FST real8 ptr mem 保存雙精度浮點數到mem 機器碼 DD mm010mmm FIST word ptr mem 保存二字節整數到mem 機器碼 DF mm010mmm FIST dword ptr mem 保存四字節整數到mem 機器碼 DB mm010mmm FSTP real4 ptr mem 保存單精度浮點數到mem并出棧 機器碼 D9 mm011mmm FSTP real8 ptr mem 保存雙精度浮點數到mem并出棧 機器碼 DD mm011mmm FSTP real10 ptr mem 保存十字節浮點數到mem并出棧 機器碼 DB mm111mmm FISTP word ptr mem 保存二字節整數到mem并出棧 機器碼 DF mm011mmm FISTP dword ptr mem 保存四字節整數到mem并出棧 機器碼 DB mm011mmm FISTP qword ptr mem 保存八字節整數到mem并出棧 機器碼 DF mm111mmm FBSTP tbyte ptr mem 保存十字節BCD數到mem并出棧 機器碼 DF mm110mmm FCMOVB ST(0),ST(i) <時傳送 機器碼 DA C0iii FCMOVBE ST(0),ST(i) <=時傳送 機器碼 DA D0iii FCMOVE ST(0),ST(i) =時傳送 機器碼 DA C1iii FCMOVNB ST(0),ST(i) >=時傳送 機器碼 DB C0iii FCMOVNBE ST(0),ST(i) >時傳送 機器碼 DB D0iii FCMOVNE ST(0),ST(i) !=時傳送 機器碼 DB C1iii FCMOVNU ST(0),ST(i) 有序時傳送 機器碼 DB D1iii FCMOVU ST(0),ST(i) 無序時傳送 機器碼 DA D1iii 三、比較指令 -------------------------------------------------------- FCOM ST(0)-ST(1) 機器碼 D8 D1 FCOMI ST(0),ST(i) ST(0)-ST(1) 機器碼 DB F0iii FCOMIP ST(0),ST(i) ST(0)-ST(1)并出棧 機器碼 DF F0iii FCOM real4 ptr mem ST(0)-實數mem 機器碼 D8 mm010mmm FCOM real8 ptr mem ST(0)-實數mem 機器碼 DC mm010mmm FICOM word ptr mem ST(0)-整數mem 機器碼 DE mm010mmm FICOM dword ptr mem ST(0)-整數mem 機器碼 DA mm010mmm FICOMP word ptr mem ST(0)-整數mem并出棧 機器碼 DE mm011mmm FICOMP dword ptr mem ST(0)-整數mem并出棧 機器碼 DA mm011mmm FTST ST(0)-0 機器碼 D9 E4 FUCOM ST(i) ST(0)-ST(i) 機器碼 DD E0iii FUCOMP ST(i) ST(0)-ST(i)并出棧 機器碼 DD E1iii FUCOMPP ST(0)-ST(1)并二次出棧 機器碼 DA E9 FXAM ST(0)規格類型 機器碼 D9 E5 四、運算指令FADD 把目的操作數 (直接接在指令后的變量或堆棧緩存器) 與來源操作數 (接在目的操作數后的變量或堆棧緩存器) 相加,并將結果存入目的操作數 FADDP ST(i),ST 這個指令是使目的操作數加上 ST 緩存器,并彈出 ST 緩存器,而目的操作數必須是堆棧緩存器的其中之一,最后不管目的操作數為何,經彈出一次后,目的操作數會變成上一個堆棧緩存器了 FIADD FIADD 是把 ST 加上來源操作數,然后再存入 ST 緩存器,來源操作數必須是字組整數或短整數形態的變數 FSUB 減 FSUBP FSUBR 減數與被減數互換 FSUBRP FISUB FISUBR FMUL 乘 FMULP FIMUL FDIV 除 FDIVP FDIVR FDIVRP FIDIV FIDIVR FCHS 改變 ST 的正負值 FABS 把 ST 之值取出,取其絕對值后再存回去。 FSQRT 將 ST 之值取出,開根號后再存回去。 FSCALE 這個指令是計算 ST*2^ST(1)之值,再把結果存入 ST 里而 ST(1) 之值不變。ST(1) 必須是在 -32768 到 32768 (-215 到 215 )之間的整數,如果超過這個范圍計算結果無法確定,如果不是整數 ST(1) 會先向零舍入成整數再計算。所以為安全起見,最好是由字組整數載入到 ST(1) 里。 FRNDINT 這個指令是把 ST 的數值舍入成整數,FPU 提供四種舍入方式,由 FPU 的控制字組(control word)中的 RC 兩個位決定 RC 舍入控制 00 四舍五入 01 向負無限大舍入 10 向正無限大舍入 11 向零舍去?
Enter 的作用相當 == push ebp 和 mov ebp,esp
這后面兩句大家很熟悉吧?函數開始一般都是這兩句
Leave 的作用相當 == mov esp,ebp 和 pop ebp
而這后面這兩句也很常見,函數調用完后一般的用到
以上的 Enter 和 leave 的作用分別函數開始和結束
Win32匯編中局部變量的使用方法可以解釋一個很有趣的現象:在DOS匯編的時候,如果在子程序中的push指令和pop指令不配對,那么返回的時候ret指令從堆棧里得到的肯定是錯誤的返回地址,程序也就死掉了。
但在Win32匯編中,push指令和pop指令不配對可能在邏輯上產生錯誤,卻不會影響子程序正常返回,原因就是在返回的時候esp不是靠相同數量的push和pop指令來保持一致的,而是靠leave指令從保存在ebp中的原始值中取回來的,也就是說,即使把esp改得一塌糊涂也不會影響到子程序的返回,當然,“竅門”就在ebp,把ebp改掉,程序就玩完了
?
?
總結
以上是生活随笔為你收集整理的汇编中各寄存器的作用(16位CPU14个,32位CPU16个)和 x86汇编指令集大全(带注释)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 王爽 汇编语言第三版 课程设计 1
- 下一篇: Microsoft Visual Stu