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

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

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

正片開始

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

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

棧有什么用?

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

棧用于維護函數(shù)調(diào)用的上下文,離開了棧函數(shù)調(diào)用就沒法實現(xiàn)。

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

寄存器

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

在這里插入圖片描述

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

在這里插入圖片描述

main函數(shù)創(chuàng)建

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

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,因為編譯器越高級函數(shù)的封裝越復(fù)雜周密,不容易我們?nèi)テ饰鰲?,我就盡量語言表達嚴謹一點吧。編譯器反匯編過程就能反應(yīng)我們棧幀創(chuàng)建的過程,這是我在網(wǎng)上找的反匯編頁面可以參考一下

在這里插入圖片描述

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

在這里插入圖片描述

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

main
_tmainCRTStartup
mainCRTStartup

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

在這里插入圖片描述

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

在這里插入圖片描述

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

在這里插入圖片描述

過程模擬如下:

在這里插入圖片描述

局部變量創(chuàng)建

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

在這里插入圖片描述


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

在這里插入圖片描述

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

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

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

函數(shù)部分

Add函數(shù)傳參時也是在將 esp 進行壓棧,但注意,這時的esp里面的值是 10,相當(dāng)于是在傳 10 這個值。傳完參緊接著就會調(diào)用函數(shù)

00C2144B E8 91 FC FF FF           call             00C210E1

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

在這里插入圖片描述

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

在這里插入圖片描述

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

形參與實參

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

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

相關(guān)文章

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

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

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

    深入sizeof的使用詳解

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

    C++?opencv圖像處理實現(xiàn)灰度變換示例

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

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

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

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

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

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

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

    QT5編譯使用QFtp的方法步驟

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

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

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

    利用QT實現(xiàn)圖片瀏覽器的示例詳解

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

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

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

最新評論