最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言進(jìn)階棧幀示例詳解教程

 更新時(shí)間:2022年02月16日 09:55:56   作者:?jiǎn)虇碳业凝堼? 
這篇文章主要為大家介紹了C語(yǔ)言進(jìn)階棧幀的示例詳解教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正片開(kāi)始

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

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

棧有什么用?

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

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

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

寄存器

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

在這里插入圖片描述

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

在這里插入圖片描述

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

我們這里隨便搞一個(gè)最簡(jiǎn)單的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,因?yàn)榫幾g器越高級(jí)函數(shù)的封裝越復(fù)雜周密,不容易我們?nèi)テ饰鰲?,我就盡量語(yǔ)言表達(dá)嚴(yán)謹(jǐn)一點(diǎn)吧。編譯器反匯編過(guò)程就能反應(yīng)我們棧幀創(chuàng)建的過(guò)程,這是我在網(wǎng)上找的反匯編頁(yè)面可以參考一下

在這里插入圖片描述

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

在這里插入圖片描述

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

main
_tmainCRTStartup
mainCRTStartup

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

在這里插入圖片描述

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

在這里插入圖片描述

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

在這里插入圖片描述

過(guò)程模擬如下:

在這里插入圖片描述

局部變量創(chuàng)建

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

在這里插入圖片描述


我們后面的 [ebp-0C0h],其實(shí)就是剛剛 sub操作,本質(zhì)上還是原來(lái)開(kāi)辟棧幀起點(diǎn) ebp 的地址,把這個(gè)地址放入edi 里面。

在這里插入圖片描述

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

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

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

函數(shù)部分

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

00C2144B E8 91 FC FF FF           call             00C210E1

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

在這里插入圖片描述

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

在這里插入圖片描述

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

形參與實(shí)參

形參確實(shí)是我在壓棧時(shí)開(kāi)辟的空間,這坨空間是獨(dú)立的,只是值是相同的,形參是實(shí)參的一份臨時(shí)拷貝,改變形參不影響實(shí)參,那返回值是怎么帶回來(lái)的呢?其實(shí)是通過(guò)寄存器。

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

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)通訊錄程序

    C語(yǔ)言實(shí)現(xiàn)通訊錄程序

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通訊錄程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊源代碼

    C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊源代碼

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊的源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 淺析順序結(jié)構(gòu)存儲(chǔ)的棧

    淺析順序結(jié)構(gòu)存儲(chǔ)的棧

    這篇文章主要介紹了順序結(jié)構(gòu)存儲(chǔ)的棧,有需要的朋友可以參考一下
    2014-01-01
  • c語(yǔ)言中全局變量的設(shè)置方式

    c語(yǔ)言中全局變量的設(shè)置方式

    這篇文章主要介紹了c語(yǔ)言中全局變量的設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Mygui中文換行問(wèn)題解決方案

    Mygui中文換行問(wèn)題解決方案

    相信大家解決了中文輸入后一定會(huì)遇到如何解決中文輸入的問(wèn)題,中文輸入換行問(wèn)題是很多gui框架都存在的一個(gè)問(wèn)題,需要的朋友可以了解下
    2012-11-11
  • C++中的循環(huán)引用

    C++中的循環(huán)引用

    雖然C++11引入了智能指針的,但是開(kāi)發(fā)人員在與內(nèi)存的斗爭(zhēng)問(wèn)題上并沒(méi)有解放,如果我門實(shí)用不當(dāng)仍然有內(nèi)存泄漏問(wèn)題,其中智能指針的循環(huán)引用缺陷是最大的問(wèn)題。下面通過(guò)實(shí)例代碼給大家介紹c++中的循環(huán)引用,一起看看吧
    2017-09-09
  • C語(yǔ)言編寫Linux守護(hù)進(jìn)程實(shí)例

    C語(yǔ)言編寫Linux守護(hù)進(jìn)程實(shí)例

    這篇文章主要介紹了C語(yǔ)言編寫Linux守護(hù)進(jìn)程實(shí)例,本文講解了守護(hù)進(jìn)程及其特性、守護(hù)進(jìn)程的編程要點(diǎn)、守護(hù)進(jìn)程代碼實(shí)例等內(nèi)容,需要的朋友可以參考下
    2015-02-02
  • C語(yǔ)言數(shù)組詳細(xì)介紹

    C語(yǔ)言數(shù)組詳細(xì)介紹

    大家好,本篇文章主要講的是C語(yǔ)言數(shù)組詳細(xì)介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C++中函數(shù)指針詳解及代碼分享

    C++中函數(shù)指針詳解及代碼分享

    這篇文章主要介紹了C++中函數(shù)指針詳解及代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • c++中創(chuàng)建.in文件的方法步驟

    c++中創(chuàng)建.in文件的方法步驟

    在本篇文章里小編給大家分享了一篇關(guān)于c++中創(chuàng)建.in文件的方法步驟的內(nèi)容以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-07-07

最新評(píng)論

永吉县| 垦利县| 广昌县| 南川市| 平度市| 庆城县| 孙吴县| 双牌县| 莎车县| 务川| 夏河县| 扬州市| 柳林县| 泰来县| 梅河口市| 平顶山市| 怀集县| 县级市| 绥芬河市| 富川| 永登县| 剑河县| 田林县| 临桂县| 开化县| 镇原县| 马鞍山市| 宜川县| 南通市| 仁怀市| 香港 | 岢岚县| 中牟县| 新乐市| 英山县| 永靖县| 阿尔山市| 常宁市| 金堂县| 千阳县| 清河县|