我對程序集很陌生,我不明白它的意思是什麼時候,在proc結束時,用ret
語句編寫一個數字。程序集中RET的含義
像這樣:
Function Proc
push ax cx
.
...body...
.
pop cx ax
ret 2
Function endp
我理解它是與棧指針應該在函數的最後返回?
請幫助我,如果你可以很容易地解釋它。
我對程序集很陌生,我不明白它的意思是什麼時候,在proc結束時,用ret
語句編寫一個數字。程序集中RET的含義
像這樣:
Function Proc
push ax cx
.
...body...
.
pop cx ax
ret 2
Function endp
我理解它是與棧指針應該在函數的最後返回?
請幫助我,如果你可以很容易地解釋它。
是的,但ret 2
也從堆棧中刪除2個字節的參數。據推測,您的函數被調用,如:
push some_parameter
call Function
在這一點上,一個cdecl
功能 - 一個「來電者清理」功能(一般使用C) - 將需要add sp, 2
「清理棧」,去掉參數。這樣的功能將以簡單的ret
結束。
一個stdcall
功能,這是你的本事,是個「被叫清理」功能(由Windows API的使用,例如)不需要add sp, 2
- 它已經被ret 2
完成。
如果你不知道它,call
把返回地址放在堆棧上(並且ret
彈出),所以你不能只是pop
在你的函數中獲取參數。
正如亞歷克斯所說,這意味着返回。 在x86彙編中,當編譯器到達此行時(例如在子例程的末尾),它會從堆棧中彈出最後一個值,該值應該是返回地址,並將其分配給IP寄存器。你可以通過編寫一個簡單的彙編代碼並使用Turbo Debugger進行編譯來更好地理解它。如果你是新手,那麼彙編程序就有一個GUI。你可以找到GUI here。
當您在子程序中彈出並向堆棧推送值時,應該存儲返回地址,因爲在子路由的末尾,需要將其推回到堆棧中,然後纔可以將return
線。
祝你好運!
可以說我有一個程序來添加兩個單詞並將總和留在EAX
。這些詞是我想傳遞給堆棧上的過程的參數。一世。E:
push word1
push word2
call addtwob
的過程看起來是這樣的:在棧上
addtwob proc
push ebp
mov ebp,esp
mov eax, [ebp+6]
add eax, [ebp+8]
pop ebp
ret 4
Endp
[ebp+6]
和[ebp+8]
地址word2
和word1
。 ret 4
只是像往常一樣返回,但隨後將4添加到堆棧指針(esp
)中,因此您不必在從調用返回後離開堆棧,因此它可以清除/平衡堆棧而無需彈出先前的推送。
你似乎在問一個關於返回的,x86_64的操作數是。在處理器遇到RET附近時由硬件跟隨的算法在Intel instruction set reference manual中示出如下;
(* Near return *)
IF instruction = near return
THEN;
IF OperandSize = 32
THEN
IF top 4 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
EIP ← Pop();
ELSE
IF OperandSize = 64
THEN
IF top 8 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
RIP ← Pop();
ELSE (* OperandSize = 16 *)
IF top 2 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
tempEIP ← Pop();
tempEIP ← tempEIP AND 0000FFFFH;
IF tempEIP not within code segment limits
THEN #GP(0); FI; //throw protected mode exception
EIP ← tempEIP;
FI;
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
THEN
ESP ← ESP + SRC;
ELSE
IF StackAddressSize = 64
THEN
RSP ← RSP + SRC;
ELSE (* StackAddressSize = 16 *)
SP ← SP + SRC;
FI;
FI;
FI;
FI;
按照這個算法每當遇到一個近返回,返回地址進行檢查,無論是在SS的限制。如果返回地址有效,則根據操作數大小將堆棧頂部彈出到RIP或EIP。
如果操作數大小爲16位,則臨時位置保存彈出的返回地址,該地址與值0x0000FFFF進行與運算,並在檢查CS限制後將其加載到EIP中。
當你的問題詢問如果有一個操作數到近RET指令操作碼會發生什麼。它取決於堆棧地址大小。根據該大小,RSP ESP或SP由操作數增加,並且在所有近RET指令在硬件上完成執行之後。
'pop cx'是OP正在查看16位代碼的一個非常明顯的標誌。出於某種原因,人們會問很多關於16位代碼的Stack Overflow問題。他們中的一些人正在製作玩具操作系統,其中大多數人正在參加大學課程,因爲某些瘋狂的原因而使用emu8086教授8086。 –
彙編不是一種語言 - 每個處理器都有自己的語言。你應該問一個特定的架構(x86,看起來)。 – ugoren
x86的答案是[here](http://download.intel.com/products/processor/manual/325383.pdf) – ugoren
題外話:'ret'是一個強大的小指令,開發漏洞軟件的中心:它根據調用堆棧的內存內容來引導程序的控制流程。如果你控制內存('strcpy',我在看你),你控制程序執行流程。 –