天天看點

棧幀 - 了解C函數調用過程

每天進步一點點。

在c程式中當計算機遇到某一個函數時,它就會跳轉過去執行這個函數,執行完畢後接着再去執行下一條函數(指令)。在執行調用函數的過程中,計算機通常還要根據函數完成一些工作,比如資料的傳遞(形參拷貝、傳回值)、記憶體的配置設定和釋放、執行控制的轉移,這些操作通過形成一個棧幀來完成。

棧幀是什麼? 棧幀(stack  frame):簡單來講,棧幀就是函數運作的環境。每個函數在被調用時都會在棧區形成一個叫棧幀的結構,這個結構中儲存了 函數參數、函數的局部變量 、函數執行完後傳回到哪裡等等一些資料 , 如圖:

棧幀 - 了解C函數調用過程

棧幀的形成通過棧指針esp和幀指針ebp的移動及相關操作來完成。 在介紹具體調用過程之前先對相關的幾個名詞作一解釋。 1、ebp:棧底指針,即指向棧幀底部的指針。 2、esp:棧頂指針,棧幀指針隻有一對。 3、call:用于儲存目前指令的下一條指令并跳轉到目标函數。 3、push:入棧(push   寄存器    保護資料)。 4、pop:出棧。 5、ptr:相當于指針,詳解: 彙編語言中的ptr(很全) 6、mov:類似于指派操作。 7、add:加法操作。 8、sub:減法操作。

讓我們通過下面這段代碼來看一看棧幀具體是如何形成并完成相關功能的。

#include <stdio.h>
#include <windows.h>

int fun( int x, int y)
{
	int c = 8;

	return c;
}

int main()
{
	int a = 2;
	int b = 4;

	int ret = fun(a, b);

	printf("you should run here!\n");

	system("pause");
	return 0;
}
           

下面是main函數調用fun函數之前進行的一些操作,包括這些: 1、參數拷貝(參數執行個體化)。 2、儲存目前指令的下一條指令,并跳轉到被調函數。 這些操作均在main中進行。

棧幀 - 了解C函數調用過程

接下來是調用fun函數并執行的一些操作,包括: 1、移動ebp、esp形成新的棧幀結構。 2、壓棧(push)形成臨時變量并執行相關操作。 3、return一個值。 這些操作在fun中進行。

棧幀 - 了解C函數調用過程

被調函數完成相關操作後需傳回到原函數中執行下一條指令,操作如下: 1、出棧(pop)。 2、回複main函數的棧幀結構。(pop ) 3、傳回main函數 這些操作也在fun中進行。

棧幀 - 了解C函數調用過程

至此,在main中調用fun的整個過程已經完成。

成于堅持,敗于止步!

【作者:果凍  http://blog.csdn.net/jelly_9】

繼續閱讀