C 語言,函式call,ret指令,棧變化等

2021-07-31 08:33:17 字數 3189 閱讀 6102

int fun(int a, int b)

int main()

int main()

int fun(int a, int b)

0093824b pop edi

0093824c pop esi

0093824d pop ebx

0093824e mov esp,ebp

00938250

pop ebp

00938251

ret

記憶體棧基礎

函式呼叫一定是 call指令

009382

a4 call fun (93710

dh)

注意到call指令之前的幾個指令

0093829c  mov         eax,dword ptr [b]  

0093829f push eax

009382a0 mov ecx,dword ptr [a]

009382a3 push ecx

這裡是引數入棧,而且是從右到左的順序

call指令(「呼叫」指令)的功能,就是以下兩點:

1. 將下一條指令的所在位址(即當時程式計數器pc的內容)入棧,

2. 並將子程式的起始位址送入pc(於是cpu的下一條指令就會轉去執行子程式)。

call之後,vs2010下按f11,debug進入fun函式裡面

push ebp
儲存上乙個函式棧的ebp, 也就是儲存main函式棧,可以發現main函式開頭也是這一句。(所以,每個函式都有自己的函式棧,但都是在整個記憶體棧中)

mov         ebp,esp  

sub esp,0cch

上一句push指令後,esp是自動往下移動了的,這乙個是把當前的esp賦值給ebp(所以,main函式的ebp,儲存了的,這裡ebp變化了,也就形成了fun函式自己的函式棧了)

sub應當是給當前函式分配棧大小的初始空間

接下來棧空間如下(灰色部分為fun函式的函式棧)

return語句,可以看到最後的返回結果存到了eax中

fun函式最後的三條指令

011c824e  mov         esp,ebp  

011c8250 pop ebp

011c8251 ret

mov esp, ebp 就是清除fun的函式棧,現在esp指向了ebp(ebp就是原來fun函式的棧底位址)

pop ebp,就是 彈出main函式的ebp

即如下的1,2操作,接著函式棧變成了,如下圖紅色框裡面的內容

ret指令

ret指令用棧中的資料,修改ip的內容,從而實現近轉移;

cpu執行ret指令時,進行下面的兩步操作:

(ip) = ((ss)*16 +(sp))

(sp) = (sp)+2

經過上面的兩條語句後,esp指向了 上圖中[call指令下乙個指令的所在位址] 那裡, ip剛好取得位址,然後回到原來,main函式的地方。

接著 esp 增加,也就是出棧,所以 main函式棧如下

回到main函式中

011c82a4  call        fun (11c710dh)  

011c82a9 add esp,8

011c82ac mov dword ptr [c],eax

printf("%d\n", c);

011c82af mov eax,dword ptr [c]

011c82b2 push eax

011c82b3 push offset string "%d" (1213ee8h)

011c82b8 call @ilt+3880(_printf) (11c6f2dh)

011c82bd add esp,8

call指令之後是 add esp 8

因為有兩個引數,所以 add esp 8 ,彈出兩個int

011c82ac

movdword

ptr[c],eax

即把fun函式返回的結果 儲存到變數c中, 函式呼叫完後,一切恢復正常(fun函式棧,早就被清除掉了)

C語言小函式 棧

include include include typedef struct stack void stacknew stack s,int elemsize void stackfree stack s static void stackgrw stack s void stackpush sta...

C語言彙編 函式呼叫棧

函式呼叫大家都不陌生,呼叫者向被呼叫者傳遞一些引數,然後執行被呼叫者的 最後被呼叫者向呼叫者返回結果,還有大家比較熟悉的一句話,就是函式呼叫是在棧上發生的,那麼在計算機內部到底是如何實現的呢?對於程式,編譯器會對其分配一段記憶體,在邏輯上可以分為 段,資料段,堆,棧 段 儲存程式文字,指令指標eip...

C語言函式棧幀解析

目錄 eax,ebx,ecx ebp 存放了指向函式棧幀棧底的位址 esp 存放了指向函式棧幀棧頂的位址 函式被呼叫時,系統會在棧區為該函式開闢一塊棧空間,這個棧空間就是該函式的函式棧幀。以main函式的呼叫為例 棧幀也叫過程活動記錄,是編譯器用來實現函式呼叫過程的一種資料結構。從邏輯上講,棧幀為乙...