關於c語言在函式呼叫過程中棧布局動態變化的討論

2021-06-20 22:14:15 字數 1034 閱讀 7268

引言:任何一種程式語言都會提供相應的機制對資料和過程進行抽象,同時還需要為資料的儲存提供記憶體訪問模型,以滿足圖靈完備性。說到程式語言就不可不提編譯器,編譯器以生成機器**的形式向程式設計師提供了兩種抽象模型:一是定義了指令格式行為及暫存器狀態的isa;二是虛擬位址空間,雖然這涉及到物理記憶體、記憶體控制器以及作業系統的軟體層。

對c語言的過程呼叫,可大致分為三個階段:呼叫前主調函式準備階段,被調函式執行階段以及控制返回階段。

1、呼叫前準備

(1):實參入棧,最後乙個引數最先入棧,第乙個引數最後入棧(要視具體平台)注意:在引數個數比較少的情況下,編譯器會將引數拷貝到暫存器中從而提高速度,當然這裡還存在暫存器儲存的問題,這些對於高階語言程式設計師來說是透明的,此時esp暫存器指向第乙個引數的低位址位置

(2):返回位址入棧,call指令的下一條指令的位址。push作為入棧指令其實是分為兩條指令完成的:r[%esp]

2、被調函式執行

(1):程式控制流程的跳轉,控制從主調函式到被調函式的轉移

(2):儲存caller的棧幀指標 pushl %ebp

(3):建立被調函式棧幀 movl %esp,%ebp,此時ebp和esp指向相同的位置,即儲存的caller的棧幀的低位址

(4):如果需要可以為區域性變數分配空間,通過subl $16, %esp的方式,分配16個位元組的區域性空間

(5):執行具體計算,直到計算完成

(6):銷毀區域性變數,通過addl $16, %esp,當然也可以一步到位movl %ebp,%esp

(7):恢復caller棧幀指標 popl %ebp

3、控制返回

ret指令其實執行了:popl %eip,將下一條指令恢復,如果函式有返回值則儲存在eax中

注意:1、一些特殊暫存器的用途,eip指令指標,esp堆疊指標,eax函式的返回值,ebx存基址,ecx迴圈時候使用。

2、在被調函式中,ebp+8是第乙個引數,ebp+12第二個引數,以此類推,如下圖

C 函式呼叫過程中棧區的變化

先簡單說一下什麼是棧幀 大多數機器的資料傳遞 區域性變數的分配和釋放通過操縱程式棧來實現。為單個過程 函式呼叫 分配的那部分棧稱為棧幀。定義 機器用棧來自傳遞過程引數,儲存返回資訊,儲存暫存器為以後恢復及本地儲存。作用 用於控制和儲存乙個函式呼叫過程的所有資訊的 組成 由兩個暫存器組成的 棧指標和幀...

C語言 函式呼叫過程(棧幀)

首先舉個栗子 include int add int x,int y int main 在這個程式裡,函式被呼叫才會發揮函式的功能,而函式的呼叫其實是乙個過程,在這個過程計算機要為函式開闢棧空間,用於本次函式臨時變數的儲存和現場保護,這塊空間稱為函式的棧幀。現場保護的作用是為了在呼叫完另乙個函式,返...

C語言函式呼叫過程 棧幀

在學習過函式宣告和定義,了解了函式的引數 實參 形參 引數的設計 函式的使用等一些函式基礎知識之後,函式逐漸變為我們編寫 時重要工具。無論是編寫時引用的庫函式,還是實現程式部分功能時使用的自定義函式,都體現函式的重要性。函式特點 使 開發更高效 提高 復用性 使 邏輯更加清晰。函式所佔據的重要地位,...