1. 程式人生 > >c語言函式呼叫過程中棧的工作原理理解

c語言函式呼叫過程中棧的工作原理理解

差不多每個程式設計師都知道,函式呼叫過程,就是層層入棧出棧的過程。

那麼這個過程中的詳細的細節是什麼樣子的呢?

閱讀了以下幾篇文章之後,對整個過程基本理解了:
C函式呼叫過程原理及函式棧幀分析
閱讀經典——《深入理解計算機系統》04
函式返回值與棧

針對自己的理解,做個記錄:

  1. 每個函式都是一個棧結構,有一個棧底指標ebp和棧頂指標esp。棧底指標在函式的執行過程中是不變的,棧頂指標會隨著函式的執行動態的增大。
  2. 在作業系統中,棧底在地址最大的地方,棧是向地址小的方向增長的。所以在棧中,申請空間時,是將棧頂指標esp向下移動,即減去一個大小。
  3. 函式的層層呼叫,就形成了連續的棧空間。
  4. 函式在呼叫被呼叫函式時,會將需要傳遞的引數由從右向左的順序入棧。被呼叫函式會根據這個關係去對應的位置取引數。
  5. 將引數入棧之後,還會將下一條指令的地址入棧。即從被呼叫函式返回之後,應該執行哪一條指令。
  6. 跳轉至被呼叫函式。被呼叫函式需要將當前的棧底指標ebp的值入棧,因為當被呼叫函式執行完畢之後,需要恢復呼叫函式的棧空間。並將ebp暫存器的值設為當前函式的棧空間的底部對應的地址,即當前esp的值。
  7. 被呼叫函式執行時,根據引數的傳入順序便可以計算出引數相對於ebp指標的位置,從而獲取變數的值。
  8. 被呼叫函式執行完畢後,如果有返回值,會將返回值存入eax暫存器中。並釋放申請的棧空間,恢復ebp和esp的值。從而使被呼叫函式能夠正常執行。
  9. 將指標暫存器指向呼叫函式壓入棧中的返回地址。
  10. 呼叫函式繼續執行,如果需要結果,則從eax暫存器中獲取

疑問:
假設棧的地址空間為0x20-0x11。
那麼
esp=0x20
ebp=0x10?
也就是會入棧一個數據(假設4個位元組)時,是先插入一個數據到0x10,0xf,0xe,0xd。這4個地址,並將esp設定為0xc?