c語言函式呼叫過程中棧的工作原理理解
阿新 • • 發佈:2018-12-17
差不多每個程式設計師都知道,函式呼叫過程,就是層層入棧出棧的過程。
那麼這個過程中的詳細的細節是什麼樣子的呢?
閱讀了以下幾篇文章之後,對整個過程基本理解了:
C函式呼叫過程原理及函式棧幀分析
閱讀經典——《深入理解計算機系統》04
函式返回值與棧
針對自己的理解,做個記錄:
- 每個函式都是一個棧結構,有一個棧底指標ebp和棧頂指標esp。棧底指標在函式的執行過程中是不變的,棧頂指標會隨著函式的執行動態的增大。
- 在作業系統中,棧底在地址最大的地方,棧是向地址小的方向增長的。所以在棧中,申請空間時,是將棧頂指標esp向下移動,即減去一個大小。
- 函式的層層呼叫,就形成了連續的棧空間。
- 函式在呼叫被呼叫函式時,會將需要傳遞的引數由從右向左的順序入棧。被呼叫函式會根據這個關係去對應的位置取引數。
- 將引數入棧之後,還會將下一條指令的地址入棧。即從被呼叫函式返回之後,應該執行哪一條指令。
- 跳轉至被呼叫函式。被呼叫函式需要將當前的棧底指標ebp的值入棧,因為當被呼叫函式執行完畢之後,需要恢復呼叫函式的棧空間。並將ebp暫存器的值設為當前函式的棧空間的底部對應的地址,即當前esp的值。
- 被呼叫函式執行時,根據引數的傳入順序便可以計算出引數相對於ebp指標的位置,從而獲取變數的值。
- 被呼叫函式執行完畢後,如果有返回值,會將返回值存入eax暫存器中。並釋放申請的棧空間,恢復ebp和esp的值。從而使被呼叫函式能夠正常執行。
- 將指標暫存器指向呼叫函式壓入棧中的返回地址。
- 呼叫函式繼續執行,如果需要結果,則從eax暫存器中獲取
疑問:
假設棧的地址空間為0x20-0x11。
那麼
esp=0x20
ebp=0x10?
也就是會入棧一個數據(假設4個位元組)時,是先插入一個數據到0x10,0xf,0xe,0xd。這4個地址,並將esp設定為0xc?