源碼:
void bar(int j, int k); // a function to call
void demo_stackframe(int a, int b, int c) {
int x;
char buffer[64];
int y;
int z;
// body of function not terribly relevant other than
bar(z, y);
}
**基于ESP 的棧幀**
** 基于EBP 的棧幀** CALL 函數調用指令
格式: CALL OPRD
功能: 過程調用指令
1. 其中OPRD為過程的目的位址.
2. 過程調用可分為段内調用和段間調用兩種.尋址方式也
可以分為直接尋址和間接尋址兩種.
3. 本指令不影響标志位.
近調用 - 調用目前代碼段(CS 寄存器目前指向的段)中的過程,有時稱為段内調用。
執行近調用時,處理器将 EIP 寄存器的值(包含 CALL 指令後面的指令的偏移量)壓入堆棧(稍後用作
傳回指令指針)。然後,處理器分支到目前代碼段中由目标操作數指定的位址。目标操作數指定代碼段中的絕對偏移量
(即相對于代碼段基址的偏移量)或相對偏移量(相對于 EIP 寄存器中指令指針的目前值的有符号位移量,此指針指向
CALL 指令後面的指令)。執行近調用時,CS 寄存器保持不變。
對于近調用,絕對偏移量在通用寄存器或記憶體位置(r/m16 或 r/m32)中間接指定。操作數大小屬性确
定目标操作數的大小(16 位或 32 位)。絕對偏移量直接加載到 EIP 寄存器。如果操作數大小屬性是 16,
則 EIP 寄存器的兩個高位位元組清除為零,得到大小最大為 16 位的指令指針。(使用堆棧指針 [ESP] 作為基址
寄存器來間接通路絕對偏移量時,使用的基址值是 ESP 在指令執行之前的值)。
在彙編代碼中,相對偏移量(rel16 或 rel32)通常指定為标簽,但是在機器代碼級别,它的編碼形式
是有符号的 16 位或 32 位立即數。此值會加到 EIP 寄存器中的值上。對于絕對偏移量,操作數大小屬性确定
目标操作數的大小(16 位或 32 位)
push ip,jmp xxx;
遠調用 - 調用目前代碼段之外的段中的過程,有時稱為段間調用。
push CS,push ip,jmp xxx;
RET 傳回指令 參數與 return 不同
功能: 當調用的過程結束後實作從過程傳回至原調用程式的下一條指令,
本指令不影響标志位.
RET指令用棧中的資料修改IP的内容 實作近轉移
IP=SS*16+SP
SP=SP+2 相當于pop IP,jmp ip
RET指令用棧中的資料修改CS和IP的内容 實作遠轉移
IP=SS*16+SP
SP=SP+2
CS=SS*16+SP
SP=SP+2
相當于pop IP,pop CS,jmp cs:ip
RET指令可以帶有一個立即數i16 則堆棧指針SP将增加
ret 08
pop ip
add sp,08
jmp ip
**進入函數前**