過程(棧幀結構是乾貨)

2021-07-04 02:59:00 字數 1596 閱讀 2484

(此處非常重要:關係到對函式呼叫和返回理解是否到位)

解說:顯然是位址80483dc的call呼叫sum函式, call指令的效果是將返回位址0x080483e1壓入棧中,再跳轉到sum函式的第一條指令(0x0804394),直到遇到ret指令為止,即是說,ret指令是乙個函式的結束標誌;

call == push ip ; jmp near ptr 標號;(壓棧後跳轉)

ret == pop ip;(出棧)

慣例——我們必須保證當乙個過程(呼叫者)呼叫另乙個過程(被呼叫者)時,

被呼叫者不會覆蓋某個呼叫者稍後會使用的暫存器的值。

int p(int x)

過程p在呼叫q之前計算y, 但它必須保證y的值在q返回後是可用的。有兩個方法可以實現:

(2)主體部分,執行過程的實際計算;(執行被呼叫函式或者過程)

(3)結束部分,恢復棧的狀態,以及過程返回;(將call指令的下一條指令的位址出棧到ip 或者叫做程式計數器pc)

我的觀點 -乾貨:

它其實是%esp的乙個副本,作用在於記錄每個執行函式或過程的棧幀結構的首位址(注意是每個函式或過程),如函式a呼叫函式b, 函式b的彙編**的第一句就要把函式a的棧幀首位址壓入棧,以便函式b結束標誌ret指令執行前的一條指令,將其呼叫者——函式a的棧幀首位址彈回到%ebp;(參看上上圖中的swap_add的彙編指令接近尾部部分)

gcc 堅持乙個x86程式設計指導方針,也就是乙個函式使用的所有棧空間必須是16位元組的整數倍;採用這個規則是為了保證訪問資料的嚴格對齊。

執行時,%esp=0x800040, 而%ebp=0x800060, scanf返回後 的棧幀圖結構, 如下:

乾貨-這裡又是乙個——很好的解釋了c語言中的傳值和傳址的問題

為什麼分配的棧幀空間中,還有沒有被使用的?

這個問題,你不要問我了,自己多思考,答案就在附近,哈哈。

乾貨-(這裡, 你也可以看到, 對於引數n,它是儲存在呼叫者的棧幀結構中的;從而解釋了為什麼取用引數的時候,都是%ebp+8;bingo!)

棧幀的結構

區域性變數 當前方法的區域性變數 基本資料型別存值,引用資料型別存位址 資料槽 slot 專門對應於我們儲存資料的位元組 乙個資料槽4個位元組,所有基本資料型別和引用資料型別基本上都是占用乙個槽,只有double和long占用兩個槽,為了 的快速分配 一般情況下非靜態方法的第乙個位置存放的是當前物件...

函式的棧幀過程

幾乎所有的函式都使用了棧,沒有棧就沒有函式,沒有區域性變數。在程式執行過程中,棧儲存了乙個函式呼叫所需要的維護資訊,也可稱為堆疊幀或者活動記錄。堆疊幀一般包括以下幾個方面 1 函式的返回位址和引數 2 臨時變數 包括函式的非靜態區域性變數以及編譯器自動生成的其他臨時變數 3 儲存的上下文 包括在函式...

函式呼叫過程(棧幀)

眾所周知,程式每呼叫乙個函式,系統都會為其開闢一塊空間,當它返回時,才收回這塊空間。程式崩潰有一部分原因就是因為無限制的呼叫函式,卻沒有及時返回,導致記憶體空間不夠。為了更好的維護這一塊空間 通常稱為棧空間 我們需要了解兩個暫存器,乙個為 esp 指向棧頂的指標 乙個為 ebp 指向棧底的指標 棧空...