先簡單說一下什麼是棧幀
大多數機器的資料傳遞、區域性變數的分配和釋放通過操縱程式棧來實現。為單個過程(函式呼叫)分配的那部分棧稱為棧幀。定義:機器用棧來自傳遞過程引數,儲存返回資訊,儲存暫存器為以後恢復及本地儲存。
作用:用於控制和儲存乙個函式呼叫過程的所有資訊的
組成:由兩個暫存器組成的 -- 棧指標和幀指標。
注意:棧的位址是從高位址往低位址延伸,函式每一次的呼叫都有自己獨立的棧幀。
棧幀示意圖
一般來說,我們將%esp
到%ebp
之間區域當做棧幀。並不是整個棧空間只有乙個棧幀,每呼叫乙個函式,就會生成乙個新的棧幀。
在函式呼叫過程中,我們需要用棧儲存以下資料:
可以去看看函式的呼叫示例的彙編**,這樣會更快理解,這裡有一些例子
簡單的來說就是先將函式壓棧,當函式呼叫結束後,再出棧
普通函式呼叫流程:
開闢棧幀空間
函式引數從右至左進行壓棧
函式返回位址進行壓棧
函式區域性變數進行壓棧
虛函式呼叫流程(大體)
查詢this指標(也就是例項)的位址
根據this指標,查詢虛函式表(函式指標陣列)的位址
從虛函式表中,取出相應的函式位址
之後的呼叫和普通函式呼叫方式一致
可以動態變化引數個數。通過棧堆分析可知,自左向右的入棧方式,最前面的引數被壓在棧底。這樣的話,除非知道引數個數,否則是無法通過棧指標的相對位移求得最左邊的引數。這樣就變成了左邊引數的個數不確定,正好和動態引數個數的方向相反。
更符合習慣。
採用這種順序,是為了讓程式設計師在使用c/c++的「函式引數長度可變」這個特性時更方便。
reference:
關於c語言在函式呼叫過程中棧布局動態變化的討論
引言 任何一種程式語言都會提供相應的機制對資料和過程進行抽象,同時還需要為資料的儲存提供記憶體訪問模型,以滿足圖靈完備性。說到程式語言就不可不提編譯器,編譯器以生成機器 的形式向程式設計師提供了兩種抽象模型 一是定義了指令格式行為及暫存器狀態的 二是虛擬位址空間,雖然這涉及到物理記憶體 記憶體控制器...
函式呼叫過程中棧幀的建立與銷毀
開始之前需要對組合語言中的一些指令進行解釋 esp 棧指標暫存器 extended stack pointer 其內存放著乙個指標,該指標永遠指向系統棧最上面乙個棧幀的棧頂。ebp 基址指標暫存器 extended base pointer 其內存放著乙個指標,該指標永遠指向系統棧最上面乙個棧幀的底...
c語言函式呼叫過程中棧的工作原理理解
差不多每個程式設計師都知道,函式呼叫過程,就是層層入棧出棧的過程。那麼這個過程中的詳細的細節是什麼樣子的呢?閱讀了以下幾篇文章之後,對整個過程基本理解了 c函式呼叫過程原理及函式棧幀分析 閱讀經典 深入理解計算機系統 04 函式返回值與棧 針對自己的理解,做個記錄 一般的作業系統 每個函式都是乙個棧...