當我們在學習c語言的時候,寫**一定會用到函式(main函式),但函式在使用過程中是如何呼叫的,當我們從彙編的角度來剖析函式的呼叫,會讓我們對函式的認識剛深一層。
注:使用的工具是vs2017
下面我將通過一段**來剖析函式是如何呼叫的
函式在呼叫的過程中,是需要為函式來開闢棧空間,用於本次函式的呼叫過程中臨時變數的儲存、現場保護,這塊空間就被稱為函式棧幀。#include
int add(int
x, int
y)
int main()
首先我們來研究一下main函式的彙編**:
前面建立棧幀的過程和main函式一樣,其中第一步是先將main函式的ebp 壓棧,目的是為了在返回時能夠返回到main函式的棧底。int main()
01061731
pop edi
01061732
pop esi
01061733
pop ebx
01061734
mov esp,ebp
01061736
pop ebp
01061737
ret
將兩數之和放入z中,並最後將z的值放在暫存器eax中
接下來將會執行pop 操作,也就是出棧,按照順序依次將edi 、esi 、ebx 出棧。然後將ebp 賦值給esp ,ebp 出棧。注:ret 指令會使得出棧一次,並將出棧的內容當做位址,將程式跳轉到該位址處。將add棧幀銷毀。01061731
pop edi
01061732
pop esi
01061733
pop ebx
01061734
mov esp,ebp
01061736
pop ebp
01061737
ret
接下來就會從call指令處繼續向下執行
將esp 向下移,將形參銷毀,把eax放入ret(ebp-20h) 中。01061849
add esp,8
0106184c mov dword ptr [ret],eax
下面就是對main棧幀的銷毀,和add棧幀的銷毀一樣。
函式呼叫過程(棧幀)
眾所周知,程式每呼叫乙個函式,系統都會為其開闢一塊空間,當它返回時,才收回這塊空間。程式崩潰有一部分原因就是因為無限制的呼叫函式,卻沒有及時返回,導致記憶體空間不夠。為了更好的維護這一塊空間 通常稱為棧空間 我們需要了解兩個暫存器,乙個為 esp 指向棧頂的指標 乙個為 ebp 指向棧底的指標 棧空...
函式棧幀(呼叫過程)
函式棧幀就是在呼叫函式是為其在棧空間上開闢了一段空間,指向過程呼叫,乙個過程呼叫包括將資料 以過程引數和返回值的形式 和控制從 的一部分傳遞到另一部分。我們以以下 為例講解整個函式呼叫過程 int my add int x,int y int main 一 呼叫main 函式 我們從main 函式的...
函式的呼叫過程 棧幀
在談棧幀之前,我們必須要先知道c c 程式記憶體的分配情況。乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放為執行函式而分配的局 部變數 函式引數 返回資料 返回位址等。其操作方式類似於資料結構中的 棧。2 堆區 heap 一般由程式設計師分配釋...