国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀

這篇具有很好參考價(jià)值的文章主要介紹了C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、 什么是函數(shù)棧幀?

函數(shù)棧幀是用于在計(jì)算機(jī)程序中實(shí)現(xiàn)函數(shù)調(diào)用的一種數(shù)據(jù)結(jié)構(gòu)。在函數(shù)調(diào)用過程中,每個(gè)函數(shù)都需要在內(nèi)存中創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量、返回地址和參數(shù)等。

  • 具體來說,函數(shù)棧幀通常包含以下部分:

  • 局部變量表:存儲(chǔ)函數(shù)的局部變量,包括基本數(shù)據(jù)類型(如整數(shù)、浮點(diǎn)數(shù)等)和對(duì)象引用(如指針)。

  • 返回地址:存儲(chǔ)函數(shù)的返回地址,即函數(shù)執(zhí)行完畢后需要跳轉(zhuǎn)到的地址。

  • 參數(shù)表:存儲(chǔ)函數(shù)的輸入?yún)?shù),通常按照傳遞的順序排列。

  • 操作數(shù)棧:用于存儲(chǔ)函數(shù)的臨時(shí)數(shù)據(jù)和中間結(jié)果,通常使用棧結(jié)構(gòu)進(jìn)行操作。

  • 當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)在內(nèi)存中創(chuàng)建一個(gè)新的棧幀,并將其壓入調(diào)用該函數(shù)的棧中。當(dāng)函數(shù)執(zhí)行完畢后,該棧幀會(huì)被彈出棧并銷毀。因此,函數(shù)棧幀在函數(shù)調(diào)用過程中起到了存儲(chǔ)和傳遞數(shù)據(jù)的作用。

函數(shù)棧幀的實(shí)現(xiàn)方式取決于具體的編程語言和編譯器。在一些高級(jí)編程語言中,編譯器通常會(huì)為每個(gè)函數(shù)自動(dòng)創(chuàng)建和銷毀棧幀,而無需程序員手動(dòng)管理。而在低級(jí)編程語言或手動(dòng)控制內(nèi)存分配的情況下,程序員需要手動(dòng)創(chuàng)建和銷毀棧幀。

二、 理解函數(shù)棧幀能解決什么問題呢?

理解函數(shù)棧幀有什么用呢?
只要理解了函數(shù)棧幀的創(chuàng)建和銷毀,以下問題就能夠很好的額理解了:

  • 局部變量是如何創(chuàng)建的?
  • 為什么局部變量不初始化內(nèi)容是隨機(jī)的?
  • 函數(shù)調(diào)用時(shí)參數(shù)時(shí)如何傳遞的?傳參的順序是怎樣的?
  • 函數(shù)的形參和實(shí)參分別是怎樣實(shí)例化的?
  • 函數(shù)調(diào)用是怎么做的?函數(shù)的返回值是如何帶會(huì)的?

讓我們一起走進(jìn)函數(shù)棧幀的創(chuàng)建和銷毀的過程中。

三、 函數(shù)棧幀的創(chuàng)建和銷毀解析

3.1、什么是棧?

棧(stack)是現(xiàn)代計(jì)算機(jī)程序里最為重要的概念之一,幾乎每一個(gè)程序都使用了棧,沒有棧就沒有函數(shù),沒有局部變量,也就沒有我們?nèi)缃窨吹降乃械挠?jì)算機(jī)語言。

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 在經(jīng)典的計(jì)算機(jī)科學(xué)中,棧被定義為一種特殊的容器,用戶可以將數(shù)據(jù)壓入棧(Push):將數(shù)據(jù)項(xiàng)添加到棧的頂部。這相當(dāng)于把數(shù)據(jù)放到棧的最上面。出棧(Pop):從棧的頂部移除數(shù)據(jù)項(xiàng)。這相當(dāng)于移除棧頂?shù)臄?shù)據(jù)項(xiàng)。但是棧這個(gè)容器必須遵守一條規(guī)則:先入棧的數(shù)據(jù)后出棧(First In Last Out, FIFO)。就像一個(gè)桶,先放的東西最后才能拿出
  • 在計(jì)算機(jī)系統(tǒng)中,棧則是一個(gè)具有以上屬性的動(dòng)態(tài)內(nèi)存區(qū)域。程序可以將數(shù)據(jù)壓入棧中,也可以將數(shù)據(jù)從棧頂彈出。壓棧操作使得棧增大,而彈出操作使得棧減小。

在經(jīng)典的操作系統(tǒng)中,??偸窍蛳略鲩L(zhǎng)(由高地址向低地址)的
在我們常見的i386或者x86-64下,棧頂由成為 esp 的寄存器進(jìn)行定位的

3.2、認(rèn)識(shí)相關(guān)寄存器和匯編指令

3.2.1 相關(guān)寄存器

  • 【eax】:通用寄存器,保留臨時(shí)數(shù)據(jù),常用于返回值
  • 【ebx】 :通用寄存器,保留臨時(shí)數(shù)據(jù)
  • 【ebp】:棧底寄存器
  • 【esp】:棧頂寄存器
  • 【eip】:指令寄存器,保存當(dāng)前指令的下一條指令的地址

3.2.2 相關(guān)匯編命令

  • 【mov】:數(shù)據(jù)轉(zhuǎn)移指令
  • 【push】:數(shù)據(jù)入棧,同時(shí)esp棧頂寄存器也要發(fā)生改變
  • 【pop】:數(shù)據(jù)彈出至指定位置,同時(shí)esp棧頂寄存器也要發(fā)生改變
  • 【add】:加法命令
  • 【sub】:減法命令
  • 【lea】 :load effective address,加載有效地址
  • 【call】:函數(shù)調(diào)用,1. 壓入返回地址 2. 轉(zhuǎn)入目標(biāo)函數(shù)
  • 【jump】:通過修改eip,轉(zhuǎn)入目標(biāo)函數(shù),進(jìn)行調(diào)用
  • 【ret】:恢復(fù)返回地址,壓入eip,類似pop eip命令

3.3、 解析函數(shù)棧幀的創(chuàng)建和銷毀

  • 首先我們達(dá)成一些預(yù)備知識(shí)才能有效的幫助我們理解,函數(shù)棧幀的創(chuàng)建和銷毀。

3.3.1 預(yù)備知識(shí)

  • 每一次函數(shù)調(diào)用,都要為本次函數(shù)調(diào)用開辟空間,就是函數(shù)棧幀的空間
  • 這塊空間的維護(hù)是使用了2個(gè)寄存器: espebp ,【ebp】 記錄的是棧底的地址, esp 記錄的是棧頂的地址

如圖所示:

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 函數(shù)棧幀的創(chuàng)建和銷毀過程,在不同的編譯器上實(shí)現(xiàn)的方法大同小異,本次演示以VS2022為例。

3.3.2 代碼和環(huán)境搭建

  • 這段代碼,如果我們?cè)赩S2019編譯器上調(diào)試,調(diào)試進(jìn)入Add函數(shù)后,我們就可以觀察到函數(shù)的調(diào)用堆棧
#include <stdio.h>

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;
}
  • 首先我們來做一些環(huán)境的搭建工作

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 首先直接在鍵盤上按下F10【筆記本按下Fn + F10】。

  • 以往寫代碼的時(shí)候,我們都知道要寫這么一個(gè)main函數(shù),程序就是從這里開始運(yùn)行的

  • 接下去在按下F10后到監(jiān)視窗口打開【調(diào)用堆?!康拇翱?/p>

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 然后就出現(xiàn)了這樣的界面。此時(shí)我們的main函數(shù)就從第13行開始運(yùn)行了

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 一直按F10,當(dāng)調(diào)試箭頭運(yùn)行到第【22行】的時(shí)候,就會(huì)自動(dòng)進(jìn)入到exe_common.inl,此時(shí)我們就可以觀察到底是哪個(gè)函數(shù)調(diào)用了main函數(shù)

  • 通過下圖可知是invoke_main這個(gè)函數(shù)調(diào)用的,我們了解到這里就可以了~~

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 然后,關(guān)掉這個(gè)【調(diào)用堆棧】的窗口后,重新調(diào)試起來
  • 調(diào)出【反匯編】【內(nèi)存】【監(jiān)視】這三個(gè)窗口

【反匯編】
C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編
【內(nèi)存】

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

【監(jiān)視】
C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

好,現(xiàn)在我們的環(huán)境已經(jīng)全部搭建好了

3.3.3 函數(shù)棧幀的創(chuàng)建

  • 接下去,我們正式開始分析函數(shù)棧幀究竟是如何創(chuàng)建的
  • 去掉符號(hào)名,方便看內(nèi)存

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 從上圖看到已經(jīng)進(jìn)入到main函數(shù)了
  • main函數(shù)是由invoke_main這個(gè)函數(shù)來進(jìn)行調(diào)用的,所以我們先畫出它的函數(shù)棧幀

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 首先看到左邊的兩個(gè)寄存器【esp】和【ebp】,分別用來維護(hù)棧頂和棧頂。
  • 對(duì)于棧來說是從【高地址】向【低地址】使用的。

  • 好,接下去的話就要執(zhí)行第一條指令。將棧中push一個(gè)ebp,也就是將ebp中的值進(jìn)行一個(gè)壓棧的操作,此時(shí)的ebp中存放的是invoke_main函數(shù)棧幀的ebp
00EE18D0  push        ebp
  • 隨著push入棧的操作,維護(hù)棧頂?shù)?strong>esp就要往上
    C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 然后我們看寄存器的變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 我們?cè)倮^續(xù)執(zhí)行一下push這句指令,你就會(huì)發(fā)現(xiàn)【esp】中所存放的地址變小了,原來存的是【ebp】中的值,只是這個(gè)存放的形式是倒著存放的,是因?yàn)橛写笮《舜鎯?chǔ)的問題

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編


  • 接下來第二條,【mov】,我們?cè)谏厦嬗兄v到過是一個(gè)數(shù)據(jù)轉(zhuǎn)移指令,這條指令的含義就是把esp的值存放到ebp中去
00EE18D1  mov         ebp,esp
  • 此時(shí)相當(dāng)于產(chǎn)生了main函數(shù)的【ebp】,這個(gè)值就是invoke_main函數(shù)棧幀的【esp】,從這里開始就要開始維護(hù)main函數(shù)的函數(shù)棧幀了

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 通過VS再來看一下,【ebp】中就會(huì)存放【esp】的地址了

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編
C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編


第三條指令

  • 接下來第三條,sub是一條減法命令,那意思就是讓esp中的地址減去一個(gè)16進(jìn)制數(shù)字【0xe4】,產(chǎn)生新的esp,此時(shí)的esp是main函數(shù)棧幀的esp
00EE18D3  sub         esp,0E4h

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 此時(shí)結(jié)合上一條指令的ebp和當(dāng)前的esp,ebp和esp之間維護(hù)了一個(gè)塊棧空間,這塊??臻g就是為main函數(shù)開辟的,就是main函數(shù)的棧幀空間,這一段空間中將存儲(chǔ)main函數(shù)中的局部變量,臨時(shí)數(shù)據(jù)以及調(diào)試信息

  • 通過圖,此時(shí)你也可以認(rèn)為【esp】指向了低地址的一塊空間
    C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 來看一下寄存器中存放的內(nèi)存變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編
C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編


第四、五、六條指令

00EE18D9  push        ebx   //將寄存器ebx的值壓棧,esp-4
00EE18DA  push        esi   //將寄存器esi的值壓棧,esp-4
00EE18DB  push        edi   //將寄存器edi的值壓棧,esp-4
  • 上面3條指令保存了3個(gè)寄存器的值在棧區(qū),這3個(gè)寄存器的在函數(shù)隨后執(zhí)行中可能會(huì)被修改,所以先保存寄存器原來的值,以便在退出函數(shù)時(shí)恢復(fù)
  • 那隨著寄存器的入棧,維護(hù)棧頂?shù)募拇嫫饕矊l(fā)生變化
  • 此時(shí)esp也隨著壓棧而變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 到VS里來看一下三次的變化:

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編


第七、八、九、十條指令

  • 下面的代碼是在初始化main函數(shù)的棧幀空間,【非常重要】
00EE18DC  lea         edi,[ebp-24h]   
00EE18DF  mov         ecx,9  
00EE18E4  mov         eax,0CCCCCCCCh  
00EE18E9  rep stos    dword ptr es:[edi] 

上面的這段代碼最后4句,等價(jià)于下面的偽代碼:

edi = ebp-0x24;
ecx = 9;
eax = 0xCCCCCCCC;
for(; ecx = 0; --ecx,edi+=4)
{
	*(int*)edi = eax;
}
  • 首先要來看的就是【lea】就是我們?cè)谏厦嬷v到過的【load effective address】加載有效地址的意思,那也就是從【ebp】這個(gè)維護(hù)棧頂?shù)募拇嫫鳒p去24h的位置,加載到寄存器【edi】里面去

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 然后再將9放到【ecx】中去;以及將【0CCCCCCCCh】這塊地址存到【eax】中去;

  • 從【edi】所存放的這塊地址的開始,每次初始化4個(gè)字節(jié)的數(shù)據(jù),dword值就是4個(gè)字節(jié)的大小

  • 這4句話的操作就是從edi開始,每次初始化4個(gè)字節(jié)的數(shù)據(jù),總共初始化ecx次,初始化的內(nèi)容為【0xCCCCCCCC】,總共初始化到ebp的地址結(jié)束

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編
C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 到這里,main函數(shù)才剛剛被初始化完成
  • 那么里面的cccccccc是初始化的什么內(nèi)容呢?–>我們來看一下
char arr[20];
printf("%s",arr);

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 可以看到上面的程序輸出“燙燙燙燙燙燙燙燙燙燙”這一串,是因?yàn)閙ain函數(shù)調(diào)用時(shí),在棧區(qū)開辟的空間的其中每一個(gè)字節(jié)都被初始化為0xCC,上圖中arr數(shù)組是一個(gè)未初始化的數(shù)組,恰好在這塊空間上創(chuàng)建的,0xCCCC(兩個(gè)連續(xù)排列的0xCC)的漢字編碼就是“燙”,所以0xCCCC被當(dāng)作文本就是“燙”,燙燙燙就這么來的

第十一、十二、十三條指令

  • 我們開始初始化三個(gè)變量,每條指令對(duì)應(yīng)上一條代碼
	int a = 10;
00EE18F5  mov         dword ptr [ebp-8],0Ah  
	int b = 20;
00EE18FC  mov         dword ptr [ebp-14h],14h  
	int c = 0;
00EE1903  mov         dword ptr [ebp-20h],0
  • 其中【mov】是數(shù)據(jù)轉(zhuǎn)移指令,也就是是將10這個(gè)值【ebp - 8】這塊地址上

  • 為什么說0Ah就是10呢?因?yàn)?Ah是10的十六進(jìn)制表示形式,在十六進(jìn)制中A值得就是10

  • 對(duì)于14h的話就是16 * 1 + 4 = 20,那就是將20這個(gè)值放到【ebp - 14】這塊地址上去

  • 最后一句就是將0這個(gè)值放到【ebp - 20】這塊地址上去

  • 對(duì)于為什么-8,-14,-20呢,這是取決于編譯器本身的,我是用的是VS2022,可能你到其他編譯器上就不一樣了

  • 這就可以得出一個(gè)結(jié)論:我們所定義的變量在棧內(nèi)存中并不是呈現(xiàn)一個(gè)連續(xù)存放的,可能是分散的

  • 接下去繼續(xù)來看這三次的存放值的變化~~

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 我們?cè)賮砜磮D,也將這些畫出來。

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編


第十四、十五、十六、十七條指令

  • 此時(shí)main函數(shù)中的變量創(chuàng)建好了,那就要調(diào)用Add函數(shù)了
00EE190A  mov         eax,dword ptr [ebp-14h]  
00EE190D  push        eax  
00EE190E  mov         ecx,dword ptr [ebp-8]  
00EE1911  push        ecx
  • 來看第一條,將【ebp-14h】這塊地址的內(nèi)容放到寄存器【eax】中去,那這個(gè)時(shí)候你就會(huì)想到這個(gè)【ebp-14】是剛才放數(shù)值20,然后壓棧。
  • 第三條就是將【ebp-8】中的內(nèi)容放到寄存器【ecx】中去,它【ebp-8】的地方存放的就是我們剛才放10的地方,然后壓棧。

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 這樣就可以看出,這兩個(gè)變量相當(dāng)于實(shí)參的一份臨時(shí)拷貝,這里就回到我們前面學(xué)的函數(shù)的形參就是實(shí)參的一份臨時(shí)拷貝

再來到VS中看看

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第十八條指令

00EE1912  call        00EE10B9
  • 對(duì)于這條【call】指令而言,比較特殊,它有兩個(gè)作用

①壓入返回地址
②轉(zhuǎn)入目標(biāo)函數(shù)

  • 這里就是要壓的是 call指令的下一條地址
00EE1917  //這條就是要壓入的地址
  • 然后我們來在vs中看一下,當(dāng)運(yùn)行到圖中的那條語句的時(shí)候就要按F11,不能按F10,和調(diào)試一個(gè)道理

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 把這塊地址壓入棧中
    C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第十九、二十、二一條指令

  • 到19條指令開始,就進(jìn)入Add函數(shù)了,這里的函數(shù)前面和在main函數(shù)中的前面也是非常的相似
  • 所以這個(gè)就是在開辟棧幀
00EE1790  push        ebp  
00EE1791  mov         ebp,esp  
00EE1793  sub         esp,0CCh  
00EE1799  push        ebx  
00EE179A  push        esi  
00EE179B  push        edi
  • 首先來看第一條指令。也就是將之前的【ebp】棧底寄存器的值壓入到棧頂中
00EE1790  push        ebp  
  • 對(duì)于此處的【ebp】,自從它在維護(hù)main函數(shù)的棧底后就沒有再動(dòng)過來,所以這里push上來的就是main函數(shù)的【ebp】

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

00EE1791  mov         ebp,esp
  • 接著再來看第二條,也就是將main函數(shù)的【esp】重新賦給【ebp】,這里要注意了,不要搞混,此時(shí)的【ebp】應(yīng)該算是在維護(hù)Add函數(shù)的棧底了

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 于是,棧就變成了這樣:

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

00EE1793  sub         esp,0CCh
  • 接著第三條,【sub】命令使得【esp】存放的地址塊減去一個(gè)CC的大小,繼續(xù)結(jié)合上面那條指令,此時(shí)Add函數(shù)的棧頂和棧底都被找到了

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 此時(shí)就相當(dāng)于是在做一個(gè)迭代的操作

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編


第二二、二三、二四條指令

00EE1799  push        ebx  
00EE179A  push        esi  
00EE179B  push        edi
  • 接下去還是一樣的三條壓棧操作
  • 來到VS中觀看【esp】的變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 接著將這三個(gè)寄存器壓入棧

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第二五、二六、二七、二八條指令

  • 對(duì)于這四條指令和上面main函數(shù)的創(chuàng)建過程類似,便不做不過分析
00EE179C  lea         edi,[ebp-0Ch]  
00EE179F  mov         ecx,3  
00EE17A4  mov         eax,0CCCCCCCCh  
00EE17A9  rep stos    dword ptr es:[edi]
  • 繼續(xù)到VS中觀看的變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第二十九條指令

  • 接下去我們進(jìn)入第二十九條指令,也就是對(duì)Add函數(shù)中存放計(jì)算總和的變量z進(jìn)行初始化操作。
  • 【mov】做數(shù)據(jù)轉(zhuǎn)移,將0放到【ebp-8】這塊地址上去
	int z = 0;
00EE17B5  mov         dword ptr [ebp-8],0 

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 然后我們?cè)贏dd的棧幀中初始化這個(gè)變量z
    C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第三十、三十一、三十二條指令

  • 接下去的三條指令就是對(duì)兩個(gè)形參的值進(jìn)行一個(gè)相加
	z = x + y;
00EE17BC  mov         eax,dword ptr [ebp+8]  
00EE17BF  add         eax,dword ptr [ebp+0Ch]  
00EE17C2  mov         dword ptr [ebp-8],eax
  • 那么上面不是只初始化了一個(gè)變量z嗎,變量x和變量y在哪里呢?
  • 我們之前有做過了一步操作,也就是將這兩個(gè)實(shí)參的拷貝進(jìn)行了一個(gè)壓棧操作,那時(shí)就說了對(duì)于這個(gè)就是形參
00EE190A  mov         eax,dword ptr [ebp-14h]  
00EE190D  push        eax  
00EE190E  mov         ecx,dword ptr [ebp-8]  
00EE1911  push        ecx
  • 此時(shí)我們就要通過這三句指令去找回這兩個(gè)形參的值,關(guān)鍵的就是【ebp+8】和【ebp+0Ch】。因?yàn)槲覀冊(cè)谌霔5臅r(shí)候【ebp】寄存器存放的地址都是逐漸變小的,因?yàn)?棧是從高地址往低地址生長(zhǎng)的,所以我們要去找回之前壓入的內(nèi)容,就要把地址加回去
  • 如下圖所示

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 找到這兩個(gè)值之后,首先將【10】放到【eax】寄存器中去,然后再將【20】在加到寄存器【eax】原有的值上去,此時(shí)【eax】中存放的便是【30】

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 注意看寄存器【eax】的變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 這里還可以直接到指令這里來看。直接將鼠標(biāo)放到【z】上面就可以看到了

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 然后再將計(jì)算出來存放在【eax】中的值再放回【ebp-8】這塊地址上去
00EE17C2  mov         dword ptr [ebp-8],eax
  • 首先到VS中來看看變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 然后修改一下之前Add函數(shù)棧幀中存放z的內(nèi)容

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第三十三條指令

  • z計(jì)算出來了,此時(shí)就要執(zhí)行【return z】這句代碼,將z返回給main函數(shù),但是函數(shù)棧幀中可不是這么做的
	return z;
00EE17C5  mov         eax,dword ptr [ebp-8]
  • 看上面的指令可以看到,是將【ebp-8】中的內(nèi)容轉(zhuǎn)存到寄存器【eax】中去
  • 從【eax】~【ebx】這些寄存器都可以用來存放臨時(shí)數(shù)據(jù),并不是說上一次用過了就不能再用了,這其實(shí)和我們?cè)诙x一個(gè)變量后進(jìn)行反復(fù)使用是一個(gè)道理。
  • 然后在Add函數(shù)調(diào)用結(jié)束后,它所對(duì)應(yīng)的函數(shù)棧幀就會(huì)被銷毀,此時(shí)被創(chuàng)建出來的臨時(shí)變量【z】就不復(fù)存在了,因?yàn)椤緕】也是存放在Add的函數(shù)棧幀中的,所以這一步的操作其實(shí)就是將我們?cè)贏dd函數(shù)中計(jì)算出來的值給保存起來,因?yàn)榧拇嫫鞫猿绦驔]有結(jié)束的話它是不會(huì)被銷毀的,我們后面還可以到這個(gè)寄存器中去取數(shù)據(jù)

3.3.4 函數(shù)棧幀的銷毀

接下去要進(jìn)行的就是函數(shù)棧幀的銷毀操作

第三十四、三十五、三十六條指令

  • 接下來就是三條pop的指令,也就是在棧頂彈出對(duì)應(yīng)的值,然后放到對(duì)應(yīng)的寄存器中去
00EE17C8  pop         edi      //在棧頂彈出一個(gè)值,存放到edi中,esp+4
00EE17C9  pop         esi     //在棧頂彈出一個(gè)值,存放到esi中,esp+4
00EE17CA  pop         ebx     //在棧頂彈出一個(gè)值,存放到ebx中,esp+4
  • 我們先到VS中來看看

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 通過圖示來看一下
    C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第三十七條指令

  • 當(dāng)給Add函數(shù)預(yù)開辟函數(shù)棧幀的時(shí)候,最后一步是把【esp】中存放的內(nèi)容給到【ebp】,也就是相當(dāng)于就是讓【ebp】指向和【esp】的同一塊空間
  • 下面這句指令就是將【ebp】中存放的內(nèi)容給到【esp】,那其實(shí)就是讓【esp】指向和【ebp】的同一塊空間
00EE17D8  mov         esp,ebp
  • 通過圖示來看一下

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 到VS中來看一下

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第三十八條指令

00EE17DA  pop         ebp
  • 這句指令很重要,因?yàn)榇藭r(shí)Add函數(shù)的函數(shù)棧幀已經(jīng)被銷毀了,此時(shí)我們要回到main函數(shù)的函數(shù)棧幀,那么兩個(gè)維護(hù)棧頂和棧底的寄存器就要發(fā)生變化,此時(shí)我們要pop的【ebp】是之前壓棧進(jìn)來的main函數(shù)的ebp
  • pop的作用:數(shù)據(jù)彈出至指定位置,同時(shí)esp棧頂寄存器也要發(fā)生改變
  • pop了之后【esp】也要發(fā)生一個(gè)變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 到VS中再來看一下變化。此時(shí)不要混淆了,棧是從高地址往低地址增長(zhǎng)的,所以棧底的地址來的大一些

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第三十九條指令

  • 這里只有一個(gè)【ret】,這個(gè)指令會(huì)從棧頂彈出一個(gè)值,那這個(gè)時(shí)候從上圖其實(shí)可以看到此時(shí)的【esp】棧頂寄存器指向的這塊地址,這塊地址是call指令的下一條指令地址,就是我們?cè)谶M(jìn)入Add函數(shù)前提前壓入的地址
00EE17DB  ret
  • 此時(shí)就會(huì)直接跳轉(zhuǎn)到call指令下一條指令的地址處,繼續(xù)往下執(zhí)行

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 再來看看【esp】的變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第四十條指令

  • 有的同學(xué)看到的就是一個(gè)【esp】的變化,【add】是加法命令,也就是將【esp】的位置加上一個(gè)8,一塊內(nèi)存空間是4,加8的話那此時(shí)【esp】是不是就來到了【edi】的位置
  • 這其實(shí)就是在【銷毀Add函數(shù)的函數(shù)形參x,y】,這下你應(yīng)該明白函數(shù)形參是在什么時(shí)候銷毀的了吧,沒錯(cuò),就是從Add函數(shù)回到main函數(shù)之后
0046185D 83 C4 08      add      esp,8
  • 我們來看看示意圖:

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 一樣,VS也來看看【esp】的變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

第四十一條指令

00EE191A  mov         dword ptr [ebp-20h],eax
  • 將eax中值,存檔到ebp-0x20的地址處,其實(shí)就是存儲(chǔ)到main函數(shù)中ret變量中,而此時(shí)eax中就是Add函數(shù)中計(jì)算的x和y的和,可以看出來,本次函數(shù)的返回值是由eax寄存器帶回來的。程序是在函數(shù)調(diào)用返回之后,在eax中去讀取返回值的。

  • 先前在Add函數(shù)中計(jì)算出來的30,首先放到【eax】寄存器中保存起來,現(xiàn)在過來好幾條指令后,它還保存在里面,我們只需要使用【mov】將數(shù)據(jù)做一個(gè)轉(zhuǎn)移即可

  • 到VS里來看看變化

C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

  • 最后main函數(shù)棧幀的銷毀也同理,這里就不再介紹了

  • 以下是這個(gè)棧的全局瀏覽圖
    C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀,C生萬物,c語言,開發(fā)語言,函數(shù)棧幀,棧幀,匯編

拓展了解:

其實(shí)返回對(duì)象時(shí)內(nèi)置類型時(shí),一般都是通過寄存器來帶回返回值的,返回對(duì)象如果時(shí)較大的對(duì)象時(shí),一般會(huì)在主調(diào)函數(shù)的棧幀中開辟一塊空間,然后把這塊空間的地址,隱式傳遞給被調(diào)函數(shù),在被調(diào)函數(shù)中通過地址找到主調(diào)函數(shù)中預(yù)留的空間,將返回值直接保存到主調(diào)函數(shù)的。具體可以參考《程序員的自我修養(yǎng)》一書的第10章。

到這里我們給大家完整的演示了main函數(shù)棧幀的創(chuàng)建,Add函數(shù)站真的額創(chuàng)建和銷毀的過程,相信大家已經(jīng)能夠基本理解函數(shù)的調(diào)用過程,函數(shù)傳參的方式,也能夠回答最開始的問題了

四、總結(jié)與開局疑難解答

① 局部變量是如何創(chuàng)建的?

  • 首先為函數(shù)分配好棧幀空間,將這塊棧幀空間初始化好后,然后給局部在棧幀里分配空間

② 為什么局部變量不初始化內(nèi)容是隨機(jī)的?

  • 因?yàn)楹瘮?shù)棧幀中的空間是預(yù)先初始化好的【0xCCCCCCCCh】,若是不為變量初始化內(nèi)容,那使用的就是初始化好后的內(nèi)容,以字符的形式打印出來便是燙燙燙燙燙燙

③ 函數(shù)調(diào)用時(shí)參數(shù)時(shí)如何傳遞的?傳參的順序是怎樣的?

  • 當(dāng)還沒有進(jìn)入函數(shù)的時(shí)候,就已經(jīng)將函數(shù)實(shí)參做了一份臨時(shí)拷貝,并從右向左壓入棧中【FILO】,當(dāng)真正進(jìn)入到函數(shù)棧幀中時(shí),通過指針的偏移量,就可以順著找回來,找到這份臨時(shí)拷貝的形參

④ 函數(shù)的形參和實(shí)參分別是怎樣實(shí)例化的?

  • 形參確實(shí)是我在壓棧的時(shí)候開辟的一塊空間,它和實(shí)參只是值相同,但是空間是獨(dú)立的,所以形參是實(shí)參的一份臨時(shí)拷貝,改變形參的值不會(huì)影響到實(shí)參

⑤ 函數(shù)調(diào)用是怎么做的?返回值是如何帶會(huì)的?

  • 當(dāng)執(zhí)行到【call】指令的時(shí)候,把call指令的下一條指令地址壓入棧中,相當(dāng)于記住了這個(gè)地址。接著進(jìn)入到函數(shù)中,當(dāng)函數(shù)執(zhí)行結(jié)束的時(shí)候,回到主函數(shù)中,再執(zhí)行【ret】指令就可以回到call指令的下一條指令地址
  • 返回值是通過寄存器帶回來的、將函數(shù)中計(jì)算出來的返回值存放到寄存器中,因?yàn)榧拇嫫鞑粫?huì)隨著函數(shù)的調(diào)用結(jié)束而被銷毀,最后再將寄存器中存放的數(shù)據(jù)轉(zhuǎn)存回對(duì)應(yīng)的內(nèi)存塊中即可

好了,函數(shù)的棧幀的創(chuàng)建與銷毀所有內(nèi)容就到這里就結(jié)束了
如果有什么問題可以私信我或者評(píng)論里交流~~
感謝大家的收看,希望我的文章可以幫助到正在閱讀的你??????文章來源地址http://www.zghlxwxcb.cn/news/detail-818835.html

到了這里,關(guān)于C語言之反匯編查看函數(shù)棧幀的創(chuàng)建與銷毀的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C語言——詳解函數(shù)棧幀的創(chuàng)建和銷毀

    C語言——詳解函數(shù)棧幀的創(chuàng)建和銷毀

    為了深入學(xué)習(xí)C語言,也為了方便理解,我學(xué)習(xí)了函數(shù)棧幀。函數(shù)棧幀的創(chuàng)建和銷毀能夠讓我更加深刻的了解編程邏輯和語法。我們學(xué)習(xí)語法和編程邏輯都是基于封裝好的知識(shí)上得。因此,我們有必要對(duì)函數(shù)棧幀的創(chuàng)建和銷毀進(jìn)行學(xué)習(xí)。本篇博客將用來介紹函數(shù)棧幀的創(chuàng)建和銷

    2024年02月12日
    瀏覽(19)
  • C語言-------函數(shù)棧幀的創(chuàng)建和銷毀------剖析描骨

    C語言-------函數(shù)棧幀的創(chuàng)建和銷毀------剖析描骨

    ??? ? ? ? ?????????????????????? ? ??? ? ? ?作者介紹:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???? ? ? ? ??? ??????????????? ? ? ? ? ? ? ?? ? ? ? ? ? ??作者id:老秦包你會(huì),? ? ? ? ??? 簡(jiǎn)單介紹:??????????????????????????????

    2024年02月14日
    瀏覽(18)
  • 【C語言__函數(shù)棧幀的創(chuàng)建和銷毀__復(fù)習(xí)篇9】

    【C語言__函數(shù)棧幀的創(chuàng)建和銷毀__復(fù)習(xí)篇9】

    目錄 前言 一、知識(shí)補(bǔ)充 二、分析創(chuàng)建和銷毀的過程 三、前言問題回答 本篇主要討論以下問題: 1. 編譯器什么時(shí)候?yàn)榫植孔兞糠峙涞目臻g 2. 為什么局部變量的值是隨機(jī)的 3. 函數(shù)是怎么傳參的,傳參的順序是怎樣的 4. 形參和實(shí)參是什么關(guān)系 5. 函數(shù)調(diào)用是怎么做的 6. 函數(shù)調(diào)

    2024年04月25日
    瀏覽(20)
  • 打通你學(xué)習(xí)C語言的任督二脈-函數(shù)棧幀的創(chuàng)建和銷毀(上)

    打通你學(xué)習(xí)C語言的任督二脈-函數(shù)棧幀的創(chuàng)建和銷毀(上)

    ? ??個(gè)人主頁:? Aileen_0v0 ??系列專欄: C語言學(xué)習(xí) ??個(gè)人格言: \\\"沒有羅馬,那就自己創(chuàng)造羅馬~\\\" 待解決疑惑: 局部變量是怎么創(chuàng)建的? 為什么局部變量的值是隨機(jī)值? 函數(shù)是怎么傳參的?傳參的順序是怎樣的? 形參和實(shí)參是什么關(guān)系? 函數(shù)調(diào)用是怎么做的? 函數(shù)調(diào)用是結(jié)束后怎么返

    2024年02月05日
    瀏覽(22)
  • 函數(shù)棧幀的創(chuàng)建和銷毀

    函數(shù)棧幀的創(chuàng)建和銷毀

    前言 觀察函數(shù)棧幀的創(chuàng)建和銷毀,不要使用太高級(jí)別的的編譯器,越高級(jí)的編譯器越不容易學(xué)習(xí)和觀察。同時(shí)在不同編譯器下,函數(shù)調(diào)用的過程中棧幀的創(chuàng)建是略有差異的,具體細(xì)節(jié)取決于編譯器的實(shí)現(xiàn) 我們?cè)趯慍語言代碼的時(shí)候,經(jīng)常會(huì)把一個(gè)獨(dú)立的功能抽象為函數(shù),所以

    2023年04月17日
    瀏覽(21)
  • 函數(shù)棧幀的創(chuàng)建與銷毀

    函數(shù)棧幀的創(chuàng)建與銷毀

    魔王的介紹:??????一名雙非本科大一小白。 魔王的目標(biāo):??努力趕上周圍卷王的腳步。 魔王的主頁:??????大魔王.?????? ?????大魔王與你分享:莫泊桑說過,生活可能不像你想象的那么好,但是也不會(huì)像你想象的那么糟。人的脆弱和堅(jiān)強(qiáng)都超乎了自己的想

    2024年02月15日
    瀏覽(20)
  • 學(xué)C的第十一天【查看匯編代碼一步步了解 函數(shù)棧幀(棧區(qū)局部變量)的創(chuàng)建和銷毀】

    學(xué)C的第十一天【查看匯編代碼一步步了解 函數(shù)棧幀(棧區(qū)局部變量)的創(chuàng)建和銷毀】

    ========================================================================= 相關(guān)代碼gitee自?。?C語言學(xué)習(xí)日記: 加油努力 (gitee.com) ========================================================================= 接上期: 學(xué)C的第十天(繼續(xù)深入學(xué)習(xí)函數(shù)、函數(shù)遞歸、練習(xí))-CSDN博客 ============================================

    2024年02月04日
    瀏覽(49)
  • 【C語言】函數(shù)棧幀的創(chuàng)建和毀銷

    【C語言】函數(shù)棧幀的創(chuàng)建和毀銷

    大家好,我是深魚~ 目錄 一、寄存器 二、棧區(qū) ?三、函數(shù)棧幀的創(chuàng)建 1.為main函數(shù)開辟棧幀? 2.在main函數(shù)中創(chuàng)建變量 3.調(diào)用Add函數(shù)前的準(zhǔn)備 ?4.為Add函數(shù)開辟棧幀 ?5.在Add函數(shù)中創(chuàng)建變量并運(yùn)算 四、函數(shù)棧幀的銷毀 6.Add函數(shù)棧幀的銷毀 7.返回main函數(shù)棧幀 【前言】 前期學(xué)習(xí)的時(shí)

    2024年02月14日
    瀏覽(15)
  • 函數(shù)棧幀的創(chuàng)建和毀銷【C語言版】

    函數(shù)棧幀的創(chuàng)建和毀銷【C語言版】

    大家好,我是深魚~ 目錄 一、寄存器 二、棧區(qū) ?三、函數(shù)棧幀的創(chuàng)建 1.為main函數(shù)開辟棧幀? 2.在main函數(shù)中創(chuàng)建變量 3.調(diào)用Add函數(shù)前的準(zhǔn)備 ?4.為Add函數(shù)開辟棧幀 ?5.在Add函數(shù)中創(chuàng)建變量并運(yùn)算 四、函數(shù)棧幀的銷毀 6.Add函數(shù)棧幀的銷毀 7.返回main函數(shù)棧幀 【前言】 前期學(xué)習(xí)的時(shí)

    2024年02月15日
    瀏覽(21)
  • 探秘函數(shù)棧幀:『 揭開函數(shù)棧幀創(chuàng)建與銷毀的神秘面紗 』

    探秘函數(shù)棧幀:『 揭開函數(shù)棧幀創(chuàng)建與銷毀的神秘面紗 』

    .. 目錄 知識(shí)點(diǎn)回顧 一、什么是棧幀(堆棧幀)? 1.內(nèi)存布局 2.常用寄存器 3.匯編指令 ????對(duì)于棧的詳細(xì)介紹 : ????函數(shù)棧幀的介紹: 二、函數(shù)調(diào)用中的棧幀 1.探究main函數(shù)棧幀的創(chuàng)建 2.對(duì)main函數(shù)中的代碼進(jìn)行分析 3.探究Add函數(shù)棧幀的創(chuàng)建? 三、函數(shù)棧幀的銷毀過程 博客引

    2024年02月06日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包