亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

【C語言】函數(shù)棧幀——函數(shù)調(diào)用時發(fā)生了什么?

Muninn / 903人閱讀

摘要:當(dāng)函數(shù)返回時,系統(tǒng)棧會彈出該函數(shù)所對應(yīng)的棧幀。四寄存器與函數(shù)棧幀每一個函數(shù)獨占自己的棧幀空間。棧幀調(diào)整具體包括。


前言

棧是函數(shù)執(zhí)行的內(nèi)存區(qū)域,是C語言運行時最重要的元素之一


一、寄存器

1.寄存器是什么?

寄存器是CPU內(nèi)部用來存放數(shù)據(jù)的一些小型存儲區(qū)域,用來暫時存放參與運算的數(shù)據(jù)和運算結(jié)果。

2.寄存器的類型

寄存器有eax,ebx,ecx,edx,還有ebp,esp。本文主要介紹最后兩個,由于寄存器不是本次博客的重點,其他請自行了解!

ESP棧指針寄存器(extended stack pointer),其內(nèi)存放著一個指針,該指針永遠(yuǎn)指向系統(tǒng)棧最上面一個棧幀的棧頂
EBP基址指針寄存器(extended base pointer),其內(nèi)存放著一個指針,該指針永遠(yuǎn)指向系統(tǒng)棧最上面一個棧幀的底部

想要了解函數(shù)棧幀,就必須先了解好這兩個地址。

ebp,esp這兩個寄存器中存放的是地址,且這兩個地址是用來維護(hù)函數(shù)棧幀的

二、棧

1.棧區(qū)是什么

棧區(qū):

用于動態(tài)地存儲函數(shù)之間的調(diào)用關(guān)系,以保證被調(diào)用函數(shù)在返回時恢復(fù)到母函數(shù)中繼續(xù)執(zhí)行。

2.棧區(qū)的常見操作

棧的最常見操作有兩種:

壓棧(push)
彈棧(pop)

用于標(biāo)識棧的屬性也有兩個:

棧頂(top)
棧底( base)。

什么意思?

可以把棧想象成一摞撲克牌。

push為棧增加一個元素的操作叫做推,相當(dāng)于在這摞撲克牌的最上面再放上一張。
pop從棧中取出一個元素的操作叫做流行,相當(dāng)于從這摞撲克牌取出最上面的一張。
pop從棧中取出一個元素的操作叫做流行,相當(dāng)于從這摞撲克牌取出最上面的一張。
base標(biāo)識棧底位置,它記錄著撲克牌最下面一張的位置。base用于防止??蘸罄^續(xù)彈棧(牌發(fā)完時就不能再去揭了)。很明顯,一般情況下,base是不會變動的。

三、函數(shù)棧幀

1.函數(shù)調(diào)用時發(fā)生了什么?

以下面代碼為例:

#define _CRT_SECURE_NO_WARNINGS 1#include int Add(int x, int y){	int z = 0;	z = x + y;	return z;}int main(){	int a = 10;	int b = 20;	int c = 0;	c = Add(a, b);	printf("%d/n", c);	return 0;}

當(dāng)中央處理器在執(zhí)行調(diào)用Add函數(shù)的時候,會從代碼區(qū)中
主要函數(shù)對應(yīng)的機(jī)器指令的區(qū)域跳轉(zhuǎn)到Add函數(shù)對應(yīng)的機(jī)器指令區(qū)域,在那里取指并執(zhí)行;當(dāng)Add函數(shù)執(zhí)行完閉,需要返回的時候,又會跳回到主要函數(shù)對應(yīng)的指令區(qū)域,緊接著調(diào)用Add后面的指令繼續(xù)執(zhí)行主要函數(shù)的代碼。

如下圖:

那么中央處理器是怎么知道要去Add函數(shù)的代碼區(qū)取指,
在執(zhí)行完Add后又是怎么知道跳回到主要函數(shù)(而不是其他未知的代碼區(qū))的呢?

這是因為

當(dāng)函數(shù)被調(diào)用時,系統(tǒng)棧會為這個函數(shù)開辟一個新的棧幀,并把它壓入棧中。這個棧幀中的內(nèi)存空間被它所屬的函數(shù)獨占,正常情況下是不會和別的函數(shù)共享的。當(dāng)函數(shù)返回時,系統(tǒng)棧會彈出該函數(shù)所對應(yīng)的棧幀。


四、寄存器與函數(shù)棧幀

每一個函數(shù)獨占自己的棧幀空間。當(dāng)前正在運行的函數(shù)的棧幀總是在棧頂。

函數(shù)棧幀:

esp和ebp之間的內(nèi)存空間為當(dāng)前棧幀,esp標(biāo)識了當(dāng)前棧幀的頂部,ebp標(biāo)識了當(dāng)前棧幀的底部。

函數(shù)調(diào)用大致包括以下幾個步驟。

(1)參數(shù)入棧:將參數(shù)從右向左依次壓入系統(tǒng)棧中。 (2)返回地址入棧:將當(dāng)前代碼區(qū)調(diào)用指令的下一條指令地址壓入棧中,供函數(shù)返回時繼續(xù)執(zhí)行。
(3)代碼區(qū)跳轉(zhuǎn):處理器從當(dāng)前代碼區(qū)跳轉(zhuǎn)到被調(diào)用函數(shù)的入口處。
(4)棧幀調(diào)整:具體包括。保存當(dāng)前棧幀狀態(tài)值,已備后面恢復(fù)本棧幀時使用(ebp入棧);將當(dāng)前棧幀切換到新棧幀(將esp值裝入ebp,更新棧幀底部);給新棧幀分配空間(把esp減去所需空間的大小,抬高棧頂);

將上面的代碼轉(zhuǎn)到反匯編模式查看

對應(yīng)觀察:


1.函數(shù)返回過程
(1)保存返回值:通常將函數(shù)的返回值保存在寄存器EAX中。
(2)彈出當(dāng)前棧幀,恢復(fù)上一個棧幀。
1.在堆棧平衡的基礎(chǔ)上,給esp加上棧幀的大小,降低棧頂,回收當(dāng)前棧幀的空間。
2.將當(dāng)前棧幀底部保存的前棧幀ebp值彈入ebp寄存器,
復(fù)出上一個棧幀。
3.將函數(shù)返回地址彈給ebi寄存器。
(3)跳轉(zhuǎn):按照函數(shù)返回地址跳回母函數(shù)中繼續(xù)執(zhí)行。


最后

本文內(nèi)容來自于《oday安全軟件漏洞分析技術(shù)》第2版與自己學(xué)習(xí)筆記所,本文僅記述自己學(xué)習(xí)歷程與僅供自己學(xué)習(xí),復(fù)習(xí)用,不做任何商業(yè)用途。

若有興趣深入了解函數(shù)棧幀,請自行查閱王清主編的《Oday安全:軟件漏洞分析技術(shù)(第2版)》一書。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/121674.html

相關(guān)文章

  • C語言知識精講②】函數(shù)棧幀的創(chuàng)建和銷毀(全程圖解)

    摘要:這里分塊講解六函數(shù)棧幀的銷毀過程一解析的作用是將棧頂?shù)臄?shù)據(jù)彈出,彈出數(shù)據(jù)儲存到相應(yīng)寄存器中。 ?前言? 讀完這篇博客,你可以明白什么? ①局部變量到底是怎么在棧上創(chuàng)建的? ②為什么局部變量不初始化為隨機(jī)值? ③函數(shù)是怎么傳參的?傳參的先后順序是什么? ④形參和實參是什么關(guān)系? ⑤函數(shù)調(diào)用是怎...

    davidac 評論0 收藏0
  • 聊聊Java的異常機(jī)制及實現(xiàn)

    摘要:是那些可能在虛擬機(jī)正常運行期間拋出的異常的超類。運行時異常定義及其子類都被稱為運行時異常。對于語言中的關(guān)鍵字和,虛擬機(jī)中并沒有特殊的字節(jié)碼指令去支持它們,都是通過編譯器生成字節(jié)碼片段以及不同的異常處理器來實現(xiàn)。 前言 在一些傳統(tǒng)的編程語言,如C語言中,并沒有專門處理異常的機(jī)制,程序員通常用方法的特定返回值來表示異常情況,并且程序的正常流程和異常流程都采用同樣的流程控制語句。Java語言...

    Towers 評論0 收藏0
  • 函數(shù)棧幀解析

    摘要:函數(shù)棧幀的銷毀匯編語言了解函數(shù)傳參函數(shù)返回值如何返回函數(shù)中變量如何初始化和賦值函數(shù)執(zhí)行結(jié)束后系統(tǒng)進(jìn)行了什么操作 文章目錄 一、什么是函數(shù)棧幀 1.寄存器2.函數(shù)棧幀3.棧幀的作用和維護(hù)4.棧幀結(jié)構(gòu)二、函數(shù)棧幀的創(chuàng)建? 1.匯編2.main函數(shù)3.Add函數(shù)的創(chuàng)建三、函數(shù)...

    MonoLog 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<