C語言函數棧幀的創建和銷毀介紹

在初學c語言中,很多時候要記的內容有點多,有時候並不能深入的瞭解它。關於函數的棧幀可以幫助我們深入瞭解函數傳參的過程,讓我們瞭解c語言。

以下是我們平時接觸過,但不瞭解的問題:

1.為什麼局部變量在未賦值前是隨機的。

2.局部變量創建的過程。

3.函數傳參,傳參的順序問題、

4.形參與實參的關系什麼。

5.調用函數是怎麼調用的,調用的過程是什麼。

6.調用函數結束後,是怎樣返回的。

這些問題我們在學校可能並不會接觸,也不會出現在考試的試卷上,但是作為計算機專業的學生,做一些認識和瞭解是很有必要的。這就相當於我們的內功,在以後深入學習時,就能夠更快的理解和認識。下面就是函數調用的整個過程,學習完之後,對以上的問題就有一個答案瞭。

函數棧幀就是系統分配給函數的空間,存放的是地址。

而esp ebp,作用是來維護函數棧幀。

esp ebp跟eax ebx ecx edx一樣,就是系統的寄存器,有一定的存儲功能。

下面就以這個函數為例

int Add(int x,int y)
{
   int z=0;
   z=x+y;
   return z;
}
int main()
{
    int a=10;
    int b=20;
    int c=0;
    c=Add(a,b);
printf("%d\n",c);
return 0;
}

main函數和其他函數一樣,main函數也是被調用的函數。

其基本邏輯是mainCRTStartup調用_tmainCRTStartup調用main函數

 程序運行時,ebp與ebp維護_tmainCRTStartup,起初esp處在棧頂指針的位置,而ebp處於棧底的位置。

 首先push,繼續壓棧操作,把ebp的地址打印到esp的位置上 ,再把esp的值代到ebp中,esp再加上oE4h的內存編號,就形成瞭下圖情況。

 此時ebp與esp就來維護main函數,在進行三次push壓棧,將ebx,esi,edi,壓到棧頂。其目的是讓系統正常的運行。

接下來接是lev mov mov的操作,就讓esp與ebp之間的空間的內容全部變為cccccc,這就是在變量未定義前,其值都是隨機值的原因。

 接下來就要定義變量abc瞭,那系統是怎樣在棧區,給abc留有空間來定義的瞭?就是以下三步來實現的~這就為abc分配瞭空間。

 

結果如圖

 

當abc定義後,接下來就是函數調用,函數傳參的過程。

 系統是先將ab的值分別放在eax ecx的寄存器中。

下面這個操作跟main函數開辟空間是類似的。

下面藍色部分,是函數的傳參過程,由圖易知。 函數傳參實際上隻是將ab的值保存在寄存器中,在臨時拷貝給x和y。

 

此時ebp-8的位置就是z所在的空間,再儲存再寄存器中。

 然後再將edi esi ebx彈出,ebp的地址傳給esp,再將ebp彈出,ebp與esp回到原來的位置,重新來維護main函數。

 

把儲存在寄存器中z的值傳給c

整個過程就是  函數棧幀的創建和銷毀。說到這些,前面所提的問題就有瞭一定的答案,可能我認識的隻是其中的一部分,但我相信在以後,會瞭解更多,瞭解更深人,在此進行講述出來,這也算是我的目標吧。

到此這篇關於C語言函數棧幀的創建和銷毀介紹的文章就介紹到這瞭,更多相關C語言函數棧幀的創建和銷毀內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: