什麼是棧幀

棧幀

那先有個問題,什麼是棧?數據結構

在數據結構中, 棧是限定僅在表尾進行插入或刪除操做的線性表。棧是一種數據結構,它按照後進先出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,須要讀數據的時候從棧頂開始彈出數據。
在計算機系統中,棧也能夠稱之爲棧內存是一個具備動態內存區域,存儲函數內部(包括main函數)的局部變量和方法調用和函數參數值,是由系統自動分配的,通常速度較快;存儲地址是連續且存在有限棧容量,會出現溢出現象程序能夠將數據壓入棧中,也能夠將數據從棧頂彈出。壓棧操做使得棧增大,而彈出操做使棧減少。
棧用於維護函數調用的上下文,離開了棧函數調用就無法實現。

而什麼是棧幀(Stack Frame)呢?
每一次函數的調用,都會在調用棧(call stack)上維護一個獨立的棧幀(stack frame).每一個獨立的棧幀通常包括:函數

  • 函數的返回地址和參數
  • 臨時變量: 包括函數的非靜態局部變量以及編譯器自動生成的其餘臨時變量
  • 函數調用的上下文
    棧是從高地址向低地址延伸,一個函數的棧幀用ebp 和 esp 這兩個寄存器來劃定範圍.ebp 指向當前的棧幀的底部,esp 始終指向棧幀的頂部;</br>
    ebp 寄存器又被稱爲幀指針(Frame Pointer);</br>
    esp 寄存器又被稱爲棧指針(Stack Pointer);
 
image

 

在函數調用的過程當中,有函數的調用者(caller)和被調用的函數(callee).
調用者須要知道被調用者函數返回值;
被調用者須要知道傳入的參數和返回的地址;指針

函數調用

函數調用分爲如下幾步:code

  • 參數入棧: 將參數按照調用約定(C 是從右向左)依次壓入系統棧中;
  • 返回地址入棧: 將當前代碼區調用指令的下一條指令地址壓入棧中,供函數返回時繼續執行;
  • 代碼跳轉: 處理器將代碼區跳轉到被調用函數的入口處;
  • 棧幀調整: </br>
    1.將調用者的ebp壓棧處理,保存指向棧底的ebp的地址(方便函數返回以後的現場恢復),此時esp指向新的棧頂位置; push ebp </br>
    2.將當前棧幀切換到新棧幀(將eps值裝入ebp,更新棧幀底部), 這時ebp指向棧頂,而此時棧頂就是old ebp mov ebp, esp </br>
    3.給新棧幀分配空間 sub esp, XXX</br>

函數返回

函數返回分爲如下幾步:orm

  • 保存被調用函數的返回值到 eax 寄存器中 mov eax, xxx
  • 恢復 esp 同時回收局部變量空間 mov ebp, esp
  • 將上一個棧幀底部位置恢復到 ebp pop ebp
  • 彈出當前棧頂元素,從棧中取到返回地址,並跳轉到該位置 ret
相關文章
相關標籤/搜索