32位微處理器指令系統之堆棧操作指令

堆棧的概念

堆棧

是在內存RAM中開闢的一段空間,利用“先進後出”或“後進先出”原則存取數據。

如果把數據壓入堆棧,則堆棧指針的值是減少的,即所謂的向下生成堆棧。

由SS:SP(16位)或SS:ESP(32位)指向棧底(棧空)或棧頂(棧不空)地址。

利用數據入棧指令PUSH和數據出棧指令POP操作堆棧。

1.數據入棧指令

指令格式:PUSH OPS

功能:將OPS中的數據壓入堆棧中。若壓入堆棧中的OPS是16位,則SP(16位CPU)或ESP(32位CPU)減2;若OPS是32位,ESP(32位CPU)減4。

PUSH一般有如下三種:

PUSH reg16/32
; 寄存器reg必須是16或32位
PUSH seg
PUSH mem16/32
; 內存中的數據必須是16或32位
PUSH imm16/32
; 將16位或32位立即數壓入堆棧

2.數據出棧指令

指令格式:POP OPD

功能:將棧頂元素彈出送到某一寄存器、段寄存器(CS除外)或內存中。注意OPS一定是16或32位。彈出棧的數據若是16位,SP或ESP加2;若數據是32位,ESP加4。

POP一般有如下三種:

POP reg16/32 
; 寄存器reg必須是16或32位
POP seg
; seg不能為CS、SS
POP mem 16/32
; 存儲器長度必須是16或32位
32位微處理器指令系統之堆棧操作指令

彈出肯定是從棧頂開始:LIFO原先的ax在下面,要等到原先的Bx彈出再彈出ax。

AX,BX入棧後原來的數據還在;只不過經過出棧後原來的數據被修改了,結果是交換了數據。

棧實際上是個中轉站。

數據的交換必須要通過第三方中轉。

MOV CX,AX
MOV DX,BX
MOV AX,DX
MOV BX,CX

這段指令實際上是利用CX,DX做中轉站交換AX,BX;道理是一樣的;

只不過棧的操作原則是LIFO。

PUSH/POP相關的其他指令

(1)存儲器操作數入棧與出棧

 PUSHW mem 
; 16位存儲器操作數入棧
PUSHD mem
; 32位存儲器操作數入棧

 PUSH WORD PTR mem(16)
PUSH DWORD PTR mem(32)

POP WORD PTR mem(16)
POP DWORD PTR mem (32)

(2)多個16位通用寄存器入棧和出棧

16位數據入棧/出棧配對使用指令:PUSHA/POPA。

PUSHA:

將AX、BX、CX、DX、SP、BP、SI、DI這8個16位通用寄存器的值依次壓入堆棧(指針減),其中SP的值是在此條指令未執行之前的值,該指令執行後,SP-16(字節)→SP。

POPA:

依次彈出堆棧中的16位字節到DI、SI、BP、SP、DX、CX、BX、AX中,該指令執行後,SP+16→SP。

(3)多個32位通用寄存器入棧與出棧

PUSHAD

將EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI這8個32位通用寄存器的值依次壓入堆棧,其中ESP的值是在此條指令未執行之前的值,指令執行後,ESP-32→ESP。

POPAD

依次彈出堆棧中的32位字到EDI、ESI、EBP、ESP、EBX、EDX、ECX、EAX中,彈出完成後,ESP+32→ESP。

上述兩組指令用於過程設計時,PUSHA和PUSHAD在過程開始時暫存通用寄存器的當前值,POPA和POPAD在過程結束時恢復通用寄存器的值,必須配對使用。

(4)16位標誌寄存器F的入棧和出棧。

PUSHF 
; 將16位標誌寄存器F的值入棧
POPF
; 將棧頂彈出2個字節送給16位標誌寄存器F,
; 或彈出送到32位標誌寄存器的低16位中。

操作碼POPF的含義是:pop flags off stack。

(5)32位標誌寄存器入棧和出棧

PUSHFD 
; 是將32位標誌寄存器EFLAGS的值

; 入棧
POPFD
; 從堆棧棧頂處連續彈出4字節送
; 給32位的標誌寄存器EFLAGS

當從堆棧中彈出4字節送給32位標誌寄存器時,只有在當前特權級為0時,才能從堆棧中彈出4字節標誌送給EFLAGS,使得EFLAGS中的I/O特權級標誌位IOPL才能被替換。

(6)ENTER和LEAVE指令

ENTER/LEAVE指令把EBP寄存器內容入棧/出棧,並在堆棧中為局部變量分配/釋放存儲空間,通常在子程序調用時使用該組指令。


分享到:


相關文章: