淺談棧幀

一、 什麼是棧幀?
什麼是棧幀,首先引用百度百科的經典解釋:“棧幀也叫過程活動記錄,是編譯器用來實現過程/函式呼叫的一種資料結構。

實際上,可以簡單理解為:棧幀就是儲存在使用者棧上的(當然核心棧同樣適用)每一次函式呼叫涉及的相關資訊的記錄單元。也許這樣感覺更復雜了,好吧,讓我們從棧開始來理解什麼是棧幀…

棧幀表示程式的函式呼叫記錄,而棧幀又是記錄在棧上面,很明顯棧上保持了N個棧幀的實體,那就可以說棧幀將棧分割成了N個記錄塊,但是這些記錄塊大小不是固定的,因為棧幀不僅儲存諸如:函式入參、出參、返回地址和上一個棧幀的棧底指標等資訊,還儲存了函式內部的自動變數(甚至可以是動態分配記憶體,alloca函式就可以實現,但在某些系統中不行),因此,不是所有的棧幀的大小都相同。

二,理解

我們拿一個例項來探討一下

這是一個在linux下執行的程式,當程式走到*p=fun時會呼叫fun函式,最後執行reboot指令關機重啟。這是為什麼呢?我們就拿棧幀來看一下。

首先了解棧幀的基本結構。

棧幀其實是兩個指標暫存器,暫存器ebp為幀指標,而暫存器esp為棧指標,當程式執行時,棧指標可以移動(大多數的資訊的訪問都是通過幀指標的)。總之簡單一句話,棧幀的主要作用是用來控制和儲存一個過程的所有資訊的。

再來看一下我們當前程式的棧幀

因為fun1中*p=&a;即p中儲存的a的地址,p指向a,
 p–;會向下走,p指向了呼叫fun1函式的返回地址,然後再將fun的地址給了P,這時候p就不能正常返回了,而是當p要返回時卻呼叫了fun函式,這時候就會執行reboot指令。