欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言進階棧幀示例詳解教程

 更新時間:2022年02月16日 09:55:56   作者:喬喬家的龍龍  
這篇文章主要為大家介紹了C語言進階棧幀的示例詳解教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正片開始

今天來講講我對棧幀創(chuàng)建與銷毀的拙見。
理解什么是棧幀首先知道什么是棧:

在數據結構中, 棧是限定僅在表尾進行插入或刪除操作的線性表。棧是一種數據結構,它按照后進先出的原則存儲數據,先進入的數據被壓入棧底,最后的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據。

棧有什么用?

在計算機系統中,棧也可以稱之為棧內存是一個具有動態(tài)內存區(qū)域,存儲函數內部(包括main函數)的局部變量和方法調用和函數參數值,是由系統自動分配的,一般速度較快;存儲地址是連續(xù)且存在有限棧容量,會出現溢出現象程序可以將數據壓入棧中,也可以將數據從棧頂彈出。壓棧操作使得棧增大,而彈出操作使棧減小。

棧用于維護函數調用的上下文,離開了棧函數調用就沒法實現。

講到這里,小朋友你是否有很多問號?那打住,我們拋開無聊的學術前文,另起爐灶。

寄存器

要講清楚棧幀就必須理解一手寄存器。尤其是 ebp,esp這2個寄存器中存放的地址,這兩個地址是用來維護函數棧幀的。

在這里插入圖片描述

寄存器有很多種這里不贅述

在這里插入圖片描述

main函數創(chuàng)建

我們這里隨便搞一個最簡單的Add函數

int   add(int x,int y)
{
       int z;
       z=x+y;
       return z;
}
int main()
{
	int  data1;
    int  data2;
    int  ret;
    while(1)
    {
       int data1,data2 = 0;
       scanf("%d %d",&data1,&data2);
       add(data1,data2);
	    return 0;
}

搞棧幀的話我的編譯器是不適合的,我是vs2019,因為編譯器越高級函數的封裝越復雜周密,不容易我們去剖析棧幀,我就盡量語言表達嚴謹一點吧。編譯器反匯編過程就能反應我們棧幀創(chuàng)建的過程,這是我在網上找的反匯編頁面可以參考一下

在這里插入圖片描述

其中反匯編用到的指針我們要清楚意義:

在這里插入圖片描述

在編譯器中,main函數也是會被其他函數調用的,調用堆棧窗口后反匯編可以看到如下字樣:

main
_tmainCRTStartup
mainCRTStartup

后面兩句意義不明的玩意兒就是在調用main函數。為什么要講這個呢?我們說每一次函數調用都要分配空間,main函數不例外也要分配棧幀空間。
以下內容和上面匯編指令表食用更佳:
首先 push ,即壓棧,就是往棧sei東西進去。push 會讓esp讓低地址走,就會在原先基礎上壓進來一個 ebp 指針。

在這里插入圖片描述

接下是 mov 指針,mov把后面的指針賦到前面去,esp給了ebp,也就是相當于在移位。

在這里插入圖片描述

接下來是 sub 減法操作,減去一個內容來使esp指針走向低地址來開辟main函數棧幀。

在這里插入圖片描述

過程模擬如下:

在這里插入圖片描述

局部變量創(chuàng)建

接下來esp已經走到那幾個內容的頭上去了,這時出現了 lea 指針,即 load effective address 加載有效地址,其實在這個指針指定對象里面放入一個地址

在這里插入圖片描述


我們后面的 [ebp-0C0h],其實就是剛剛 sub操作,本質上還是原來開辟棧幀起點 ebp 的地址,把這個地址放入edi 里面。

在這里插入圖片描述

接下來的連續(xù) mov 時在把從edi 開始的 30h 這么多個空間里面的 dword(double word-四字節(jié)數據)全部初始化成 eax 里面 “0CCCCCCCCh”的內容,保證為main函數預開辟的內存全變成 “CCCCCCCCh”,這么說來改的還是蠻多的。
接下來當我們創(chuàng)建變量時,比如 int a = 10;就會出現類似下面字樣:

int a = 10;                      
00C2142E C7 45 EC 0A 00 00 00 mov             dword ptr [ebp-8h],0Ah

這里就是在創(chuàng)建局部變量了, ebp指針減了 8h,這個 8h 就是給a留的位子**(這里的 h 是編譯器給的標識,我們只需要明白這是一個十六進制數)**就行了。所以總結一下,其實創(chuàng)建方式與main函數沒有太大出入。

函數部分

Add函數傳參時也是在將 esp 進行壓棧,但注意,這時的esp里面的值是 10,相當于是在傳 10 這個值。傳完參緊接著就會調用函數

00C2144B E8 91 FC FF FF           call             00C210E1

call 指針作用就是調用函數,F11 執(zhí)行call指令后會發(fā)現在跳轉到作用的同時,他會把 call指令的下一條指令的地址傳到里面,在頂上壓一個main函數的ebp ,esp又會跑到最上面,一但函數執(zhí)行完后返回就會很自然的回到該地址。

在這里插入圖片描述

在main函數的 ebp 上面又會傳統藝能,以相同的方式開辟 Add 函數的空間,又初始化成全 c,以相同方式創(chuàng)建臨時變量……
這時你可能會注意到傳進函數的 x,y去哪里了?其實已經為他準備好了,在返回進行下一項指令時,x,y就會乖乖跑到這片空間儲存

在這里插入圖片描述

Add函數完成后回把傳的參返回, 就是我們的 pop 指針,即出棧,這里參數每從棧頂pop一次 esp 指針就會上移一個單位,ebp也會隨之退回一個單位,利用指針的偏移量找回他的形參,最后返回值ret,其邏輯本質上就是彈出main ebq那里的下一項指令的地址。
我們走出函數后,esp,ebq會回收,這時這塊空間就會直接銷毀,挫骨揚灰。
整個函數部分就完美的呈現出來了。

形參與實參

形參確實是我在壓棧時開辟的空間,這坨空間是獨立的,只是值是相同的,形參是實參的一份臨時拷貝,改變形參不影響實參,那返回值是怎么帶回來的呢?其實是通過寄存器。

以上就是C語言進階棧幀示例詳解教程的詳細內容,更多關于C語言棧幀的資料請關注腳本之家其它相關文章!

相關文章

  • 必須知道的C語言八大排序算法(收藏)

    必須知道的C語言八大排序算法(收藏)

    這篇文章主要介紹了C語言八大排序算法的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-10-10
  • 深入sizeof的使用詳解

    深入sizeof的使用詳解

    本篇文章是對sizeof的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++?opencv圖像處理實現灰度變換示例

    C++?opencv圖像處理實現灰度變換示例

    這篇文章主要為大家介紹了C++?opencv圖像處理灰度變換的實現示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 淺談C++中char型變量的地址輸出

    淺談C++中char型變量的地址輸出

    下面小編就為大家?guī)硪黄獪\談C++中char 型變量的地址輸出。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • C++中cin.getline()和getline()函數的區(qū)別小結

    C++中cin.getline()和getline()函數的區(qū)別小結

    這篇文章主要介紹了C++中cin.getline()和getline()函數區(qū)別的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • C++ OpenCV讀寫XML或YAML文件的方法詳解

    C++ OpenCV讀寫XML或YAML文件的方法詳解

    XML是一種元標記語言。所謂元標記,就是開發(fā)者可以根據自身需要定義自己的標記。YAML是一個可讀性高,用來表達資料序列的格式。本文將通過C++和OpenCV實現這兩種文件的讀寫,需要的可以參考一下
    2022-05-05
  • QT5編譯使用QFtp的方法步驟

    QT5編譯使用QFtp的方法步驟

    這篇文章主要介紹了QT5編譯使用QFtp的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • 詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法

    詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法

    這篇文章主要介紹了詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • 利用QT實現圖片瀏覽器的示例詳解

    利用QT實現圖片瀏覽器的示例詳解

    這篇文章主要和大家分享一個小案例:利用QT制作一個小的圖片瀏覽器,要求可以顯示jpg、jpeg、png、bmp,還可以從電腦上拖動圖到窗口并顯示出來,感興趣的可以了解一下
    2023-02-02
  • Linux下用Valgrind做檢查(防止內存泄露)

    Linux下用Valgrind做檢查(防止內存泄露)

    Valgrind是一款基于模擬linux下的程序調試器和剖析器的軟件套件,可以運行于x86, amd64和ppc32架構上。valgrind包含一個核心,它提供一個虛擬的CPU運行程序,還有一系列的工具,它們完成調試,剖析和一些類似的任務
    2014-01-01

最新評論