差不多每個程式設計師都知道,函式呼叫過程,就是層層入棧出棧的過程。
那麼這個過程中的詳細的細節是什麼樣子的呢?
閱讀了以下幾篇文章之後,對整個過程基本理解了:
c函式呼叫過程原理及函式棧幀分析
閱讀經典——《深入理解計算機系統》04
函式返回值與棧
針對自己的理解,做個記錄:
(一般的作業系統)
每個函式都是乙個棧結構,有乙個棧底指標ebp和棧頂指標esp。棧底指標在函式的執行過程中是不變的,棧頂指標會隨著函式的執行動態的增大。
在作業系統中,棧底在位址最大的地方,棧是向位址小的方向增長的。所以在棧中,申請空間時,是將棧頂指標esp向下移動,即減去乙個大小。
函式的層層呼叫,就形成了連續的棧空間。
函式在呼叫被呼叫函式時,會將需要傳遞的引數由從右向左的順序入棧。被呼叫函式會根據這個關係去對應的位置取引數。
跳轉至被呼叫函式。被呼叫函式需要將當前的棧底指標ebp的值入棧,因為當被呼叫函式執行完畢之後,需要恢復呼叫函式的棧空間。並將ebp暫存器的值設為當前函式的棧空間的底部對應的位址,即當前esp的值。
被呼叫函式執行時,根據引數的傳入順序便可以計算出引數相對於ebp指標的位置,從而獲取變數的值。
被呼叫函式執行完畢後,如果有返回值,會將返回值存入eax暫存器中。並釋放申請的棧空間,恢復ebp和esp的值。從而使被呼叫函式能夠正常執行。
將指標暫存器指向呼叫函式壓入棧中的返回位址。
呼叫函式繼續執行,如果需要結果,則從eax暫存器中獲取
疑問:假設棧的位址空間為0x20-0x11。
那麼ebp=0x20
esp=0x10?
如果入棧乙個資料(假設4個位元組)時,是插入乙個資料到0x10,0xf,0xe,0xd。這4個位址,並將esp設定為0xc?
即ebp指向棧空間開始的位元組。esp指向棧頂端的下乙個位元組?
C 函式呼叫過程中棧區的變化
先簡單說一下什麼是棧幀 大多數機器的資料傳遞 區域性變數的分配和釋放通過操縱程式棧來實現。為單個過程 函式呼叫 分配的那部分棧稱為棧幀。定義 機器用棧來自傳遞過程引數,儲存返回資訊,儲存暫存器為以後恢復及本地儲存。作用 用於控制和儲存乙個函式呼叫過程的所有資訊的 組成 由兩個暫存器組成的 棧指標和幀...
C語言 函式呼叫過程(棧幀)
首先舉個栗子 include int add int x,int y int main 在這個程式裡,函式被呼叫才會發揮函式的功能,而函式的呼叫其實是乙個過程,在這個過程計算機要為函式開闢棧空間,用於本次函式臨時變數的儲存和現場保護,這塊空間稱為函式的棧幀。現場保護的作用是為了在呼叫完另乙個函式,返...
C語言函式呼叫過程 棧幀
在學習過函式宣告和定義,了解了函式的引數 實參 形參 引數的設計 函式的使用等一些函式基礎知識之後,函式逐漸變為我們編寫 時重要工具。無論是編寫時引用的庫函式,還是實現程式部分功能時使用的自定義函式,都體現函式的重要性。函式特點 使 開發更高效 提高 復用性 使 邏輯更加清晰。函式所佔據的重要地位,...