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

C語言函數(shù)調(diào)用堆棧詳情分析

 更新時間:2022年07月14日 15:52:39   投稿:hqx  
這篇文章主要介紹了C語言函數(shù)調(diào)用堆棧詳情分析,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

 一、C函數(shù)棧幀開辟以及回退過程

__cdecl(C語言默認(rèn)調(diào)用方式,函數(shù)參數(shù)8字節(jié)以內(nèi),使用push。本節(jié)采用此方式)

main函數(shù)的棧幀調(diào)用sum函數(shù)的棧幀,sum函數(shù)棧幀使用完了以后回退都是怎么進(jìn)行的,要搞清楚這個問題必須得看匯編代碼,匯編代碼分為兩種:inter x86(windows)和AT&T(unix)。這兩種匯編非常相似,x86的匯編是從右向左看,unix的匯編是從左向右看的。

局部變量都是通過棧底指針ebp偏移訪問,不生成符號,不屬于數(shù)據(jù),屬于指令。

形參壓棧在C/C++中是從右向左壓棧,因為要支持可變長參數(shù),如果從左向右,編譯器就不知道用戶傳入了多少實參,形參內(nèi)存是在調(diào)用函數(shù)棧幀中開辟,每壓棧一個實參,都會開辟一個形參的空間,棧頂指針esp都會減4字節(jié)。

實參壓棧完成后需要調(diào)用call指令來執(zhí)行sum函數(shù),執(zhí)行完sum函數(shù)后,執(zhí)行完sum函數(shù)后需要回到調(diào)用指令(call)的下一條指令繼續(xù)執(zhí)行。

call指令做兩件事:

  • 1.把下一行指令的地址入棧
  • 2.jmp跳轉(zhuǎn)

??臻g圖:

執(zhí)行call指令后,程序調(diào)到這里,不是sum函數(shù)的指令部分

在編譯階段,所有匯編指令代碼引用符號的地方全部不是合法的地址(因為我們當(dāng)前文件可能引用外部的符號,而編譯階段是獨立編譯的,我們鏈接的時候才會進(jìn)行符號解析、合并符號表等操作,之后再給符號分配內(nèi)存地址),對于數(shù)據(jù)符號來說是零地址,對于函數(shù)符號來說是-4。那么當(dāng)我們在鏈接階段符號解析完成以后,得到每一個符號的具體地址,給數(shù)據(jù)符號分配的地址是絕對地址,給函數(shù)符號分配的地址是與下一行指令地址的一個偏移量,這樣當(dāng)程序需要跳轉(zhuǎn)到某個函數(shù)地址的時候,取出PC寄存器保存的地址與該偏移量相加就得到函數(shù)的入口地址。

計算相對偏移量后就進(jìn)入了sum函數(shù),先執(zhí)行下面一段指令,才執(zhí)行我們寫的sum函數(shù)

每次執(zhí)行一個函數(shù)前要執(zhí)行三個操作:

  • 把調(diào)用方的棧底地址入棧(push ebp),讓ebp指針指向當(dāng)前函數(shù)的棧底(mov ebp,esp)
  • 移動棧頂指針esp,給被調(diào)用函數(shù)開辟棧幀(sub esp 44h)
  • 初始化新棧幀內(nèi)存,把esp和ebp之間所有的棧內(nèi)存全部初始化成0xCCCCCCCC(rep stos dword ptr [edi])無效值。

Linux為棧幀不分配初始值,windows會分配初始值,為0xCCCCCCCC(-858993460)

然后執(zhí)行sum函數(shù)的指令:

局部變量通過棧底指針ebp負(fù)向偏移訪問,形參通過ebp正向偏移訪問,eax為a+b的計算結(jié)果,將計算結(jié)果賦值給temp,return的時候?qū)emp的值賦值給eax,給調(diào)用方返回

棧幀清退:

可以看到,開辟棧幀的時候我們對占內(nèi)存進(jìn)行了初始化,但是棧幀清退的時候僅僅就是修改了esp和ebp,沒有做其他任何操作,如果我們此時通過一些手段去訪問已被清退棧幀的內(nèi)存,還是可以訪問到的,因為數(shù)據(jù)還存在

參數(shù)清除:

sum函數(shù)執(zhí)行完成后,從PC寄存器中取出地址繼續(xù)執(zhí)行,這里PC寄存器存放的是call指令的下一行地址,這條指令做的操作是回退形參變量占的內(nèi)存,形參內(nèi)存由調(diào)用方開辟和釋放。sum函數(shù)返回值由eax寄存器帶回來。

在被調(diào)用方執(zhí)行完成后,通過pop ebp就知道應(yīng)該回到哪(恢復(fù)棧底),再通過ret指令就知道回到哪以后從哪一行指令開始運行(取出棧頂元素放到PC寄存器里面,而棧頂元素存的就是call的下一行地址)
sum函數(shù)棧底保存的是main的棧底地址,main函數(shù)棧底保存的是調(diào)用main的函數(shù)的棧底地址

二、C函數(shù)調(diào)用約定和返回值

函數(shù)調(diào)用約定和返回值

到此這篇關(guān)于C語言函數(shù)調(diào)用堆棧詳情分析的文章就介紹到這了,更多相關(guān)C函數(shù)調(diào)用堆棧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c語言執(zhí)行Hello?World背后經(jīng)歷的步驟

    c語言執(zhí)行Hello?World背后經(jīng)歷的步驟

    這篇文章介紹了c語言執(zhí)行Hello?World背后經(jīng)歷的步驟,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • C++無鎖隊列的原理與實現(xiàn)示例

    C++無鎖隊列的原理與實現(xiàn)示例

    C++無鎖隊列是一種多線程編程技術(shù),它可以在不使用鎖的情況下實現(xiàn)線程安全的隊列,本文就來詳細(xì)的介紹一下C++無鎖隊列的原理與實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 如何使用C語言實現(xiàn)細(xì)菌的繁殖與擴散

    如何使用C語言實現(xiàn)細(xì)菌的繁殖與擴散

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)細(xì)菌的繁殖與擴散,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C語言模擬實現(xiàn)掃雷游戲

    C語言模擬實現(xiàn)掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了C語言模擬實現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • C語言文件操作與相關(guān)函數(shù)介紹

    C語言文件操作與相關(guān)函數(shù)介紹

    文件(file)一般指存儲在外部介質(zhì)上數(shù)據(jù)的集合,比如我們經(jīng)常使用的.txt, .bmp, jpg. .exe,.rmvb等等,下面這篇文章主要給大家介紹了關(guān)于C語言文件操作的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • C++實現(xiàn)教務(wù)管理系統(tǒng)

    C++實現(xiàn)教務(wù)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)教務(wù)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Qt實現(xiàn)日志文件的滾動寫入

    Qt實現(xiàn)日志文件的滾動寫入

    這篇文章主要為大家介紹了如何使用Qt實現(xiàn)日志文件的滾動寫入功能,在日志文件達(dá)到10MB時創(chuàng)建新的日志文件,并且在總?cè)罩疚募笮∵_(dá)到10GB時開始覆蓋最早的日志文件,需要的可以參考下
    2024-11-11
  • C語言中如何判斷質(zhì)數(shù)

    C語言中如何判斷質(zhì)數(shù)

    這篇文章主要介紹了C語言中的判斷質(zhì)數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • C++基礎(chǔ)入門教程(六):為什么創(chuàng)建類的時候要用new?

    C++基礎(chǔ)入門教程(六):為什么創(chuàng)建類的時候要用new?

    這篇文章主要介紹了C++基礎(chǔ)入門教程(六):為什么創(chuàng)建類的時候要用new?本文講解了使用new創(chuàng)建動態(tài)結(jié)構(gòu)體、為什么要有new、自動存儲(自動變量、局部變量)、動態(tài)存儲、vector和array等內(nèi)容,需要的朋友可以參考下
    2014-11-11
  • 使用Inotify 監(jiān)控目錄與文件的方法詳解

    使用Inotify 監(jiān)控目錄與文件的方法詳解

    本篇文章是對使用Inotify 監(jiān)控目錄與文件的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評論

大丰市| 沐川县| 轮台县| 灵宝市| 恩平市| 象州县| 罗田县| 五大连池市| 中牟县| 西和县| 临沭县| 巴南区| 普安县| 全南县| 平阳县| 广安市| 井研县| 崇明县| 平凉市| 平泉县| 浦县| 灯塔市| 赫章县| 沈阳市| 筠连县| 淄博市| 银川市| 三台县| 乐平市| 铜梁县| 南安市| 宜州市| 麻栗坡县| 阿城市| 平邑县| 邻水| 麻阳| 阳江市| 马尔康县| 专栏| 句容市|