C 從彙編角度詳解函式呼叫棧

2021-10-03 20:45:51 字數 1596 閱讀 9864

先來看一段**:

int

sum(

int a,

int b)

intmain()

有兩個問題:

main函式呼叫sun,sum執行完之後怎麼知道回到哪個函式?

sum函式執行完,回到main之後,怎麼知道從哪一行指令繼續執行?

我們現在從彙編角度看這段**:

首先main還是會先開闢棧幀

mov         dword ptr [ebp -4]

,0ah //int a = 10;

mov dword ptr [ebp -8]

,14h //int b = 20;

mov eax,dword ptr [ebp -8]

//esp儲存main函式棧頂的位址 ebp存放main函式棧底位址

下面就到sum函式了

push		ebp

mov ebp,esp

sub esp,

4ch//上述這三行彙編**其實就是函式左括號({)所對應的**,這三行**的作用其實就是為sum函式開闢棧幀

mov dword ptr [temp],0

//int temp = 0

mov eax,dword ptr [ebp +8]

//訪問a

add eax,dword ptr [ebp + och]

//a+b

mov dword ptr [temp]

,eax

mov eax,dword ptr [temp]

//在return之後temp這個變數會被釋放,所以把temp的值放在eax這個暫存器中

//**函式返回值如果小於等於四個位元組,存放在eax暫存器中,如果大於4小於8位元組放在eax和ebx,如果大於8位元組,則產生乙個臨時量返回其位址**

mov esp,ebp

pop ebp

ret//ret的兩種作用:結束呼叫;執行出棧操作,把主函式中呼叫指令的下一條指令的位址放入cpu的pc暫存器裡面(pc暫存器存放cpu要執行嚇一跳指令的位址)

從彙編的角度看棧

大家都知道,棧區是儲存函式,區域性變數的一塊記憶體區域。那麼讓我們從彙編的角度,來看看函式的執行過程。首先,當我們使用pushl將資料入棧時,棧頂會移動,以容納新增加的值。實際上,我們能不斷將值入棧,棧會在記憶體中保持向下增長,知道存放 或資料的地方。那麼,我們如何知道棧頂位址呢?棧暫存器 esp總...

C語言彙編 函式呼叫棧

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

從彙編的角度分析函式呼叫過程(1)

函式的引數傳遞有2種方式 堆疊方式 暫存器方式。如果是堆疊方式傳遞的,就需要定義函式引數在堆疊中的傳遞順序,並約定函式被呼叫之後,由誰來平衡堆疊 如果是暫存器方式傳遞的,就需要確定引數存放在哪個暫存器中。每一種方式都有其優缺點,而且與使用的程式語言有關係,不存在哪種方式好與壞。我們在開發中經常遇到呼...