基礎類 呼叫堆疊

2021-07-10 23:56:41 字數 1283 閱讀 8152

本部落格中的很多術語,模型並非教科書或業界認可的,而是個人分析後根據理解所取定義的。這些術語、模型存在很多片面理解,但有助於本人對系統的理解和學習。希望**本部落格的各位朋友慎重,對大家有幫助的我感到很榮幸,有錯誤的,敬請批評指正。

一般的應用程式,都是從main()函式開始執行,在實現程式的功能時,通常每個功能都有乙個入口函式,如getfreq(),獲取某個測試點的訊號頻率值。getfreq()方法在實現其功能時,需要呼叫很多方法,比如有三個getstepl2_1(),getstepl2_2(),getstepl2_3()。在這三個函式自身的實現時,也會呼叫其他的方法,需要不斷的巢狀呼叫。比如getstepl2_1()呼叫getstepl3_1(),getstepl3_2(),getstepl3_3();getstepl2_2()呼叫getstepl3_1(),getstepl3_2();getstepl2_3()呼叫getstepl3_1()。(注意,這裡有意識的使用getsteplx_x()這樣的命名方式來區分不同深度的方法)巢狀呼叫的終點是呼叫儀器的驅動。根據巢狀的深度,可以將不同的函式歸納為不同的深度。呼叫深度的定義是這樣的,getfreq()為第一級,getstepl2_1(),getstepl2_2(),getstepl2_3()為第二級;getstepl3_1(),getstepl3_2(),getstepl3_3()為第**,一次類推。其拓撲結構向樹根的分支。

上例中,

getfreq()--->getstepl2_1()--->getstepl3_1(),

getfreq()--->getstepl2_1()--->getstepl3_2(),

getfreq()--->getstepl2_1()--->getstepl3_3(),

getfreq()--->getstepl2_2()--->getstepl3_1(),

getfreq()--->getstepl2_2()--->getstepl3_2(),

getfreq()--->getstepl2_3()--->getstepl3_1()

都是呼叫鏈,共有六條呼叫鏈,每條呼叫鏈都會對應乙個呼叫堆疊。

當然,這些呼叫堆疊的拓撲結構並不是平行的,而是樹狀的,很多呼叫鏈都有共同的部分。

在函式巢狀呼叫時,以函式為單元,每當有個函式被呼叫時,都被壓入堆疊(這裡不是以呼叫處的斷點,呼叫者的區域性變數這些方面分析,而是以整個函式為乙個基本單元,壓棧和出棧都是以函式為單位)。因此,形成乙個函式呼叫堆疊。從此可以分析,位於呼叫堆疊棧頂的一定是呼叫模型中,深度最深的。比如上例中模組提供的驅動函式位於每個呼叫鏈的棧頂。在每條呼叫鏈中,getfreq()都是位於棧底的。這和堆疊的特性一樣,最晚入棧的在棧頂。

函式呼叫堆疊

一 函式呼叫堆疊 認真體會每一行指令位址!include intsum int a,int b mov ebp,esp 讓esp回退到ebp的位置,回退棧幀的過程中,沒有對棧幀中的值進行清0的操作 pop ebp 出棧並把出棧的值賦給ebp int main 下圖為上面示例函式,程式在sum函式中,...

函式呼叫堆疊

一 棧 1 傳統的棧 被定義為乙個特殊的容器,使用者可以將資料壓入棧中,也可以將壓入 棧中的資料彈出,但必須遵守一條規則 先進後出。2 計算機系統中的棧 是乙個有以上屬性的動態記憶體區域,壓棧操作使得棧增大,彈出操作使棧減小。棧通常是向下增長的。3 最重要的是棧儲存了乙個函式呼叫所需的維護資訊,這通...

函式呼叫堆疊

乙個函式的執行在棧上開闢記憶體。在函式呼叫時,第乙個進棧的是主函式呼叫語句的下一條可執行語句的位址,然後是函式的各個引數。在大多編譯器中,引數是由右往左入棧的,然後再是函式中的區域性變數。下面給乙個例項 int sum int a,int b int main 其中,main函式的反彙編指令 其中,...