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

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

 更新時(shí)間:2022年02月21日 14:45:39   作者:tjh94512  
這篇文章主要為大家詳細(xì)介紹了C語言函數(shù)棧幀的創(chuàng)建與銷毀,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

前言

大家在學(xué)習(xí)的時(shí)候一定有以下困惑: 局部變量是怎么創(chuàng)建的?為什么局部變量的值是隨機(jī)值?函數(shù)是怎么傳參?傳參的順序是怎樣的?形參與實(shí)參是什么關(guān)系?函數(shù)調(diào)用是怎么做到的?函數(shù)調(diào)用完成不是銷毀了嗎,如何帶回的返回值?

以上這些都可以通過了解函數(shù)棧幀的創(chuàng)建與銷毀來理解。接下來我就帶大家來了解函數(shù)棧幀的創(chuàng)建與銷毀。

本次使用的編輯器是VS2013,因?yàn)樵较冗M(jìn)的編輯器,越不容易觀察到底層。好了,我們回到正題。

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

1.寄存器

寄存器里有eax,ebx,ecx,edx,ebp,esp等,我們今天要重點(diǎn)了解的是ebp與esp這兩個(gè)寄存器。

2.ebp與esp

這兩個(gè)寄存器中存放的是地址,整兩個(gè)地址使用來維護(hù)函數(shù)棧幀的。每一個(gè)函數(shù)調(diào)用,都要在棧區(qū)創(chuàng)建一個(gè)空間,這塊空間叫做函數(shù)棧幀,用esp與ebp來維護(hù)。

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

1.代碼塊

#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 ret = Add(a, b);
	printf("ret=%d\n", ret);
	return 0;
}

這個(gè)代碼只是一個(gè)很簡(jiǎn)單的實(shí)現(xiàn)了加法函數(shù),不用多說。

2.調(diào)用堆棧

接下來開始調(diào)試程序來看底層代碼如何實(shí)現(xiàn),首先打開調(diào)用堆棧

在這里插入圖片描述

從這里可以清楚地知道,main函數(shù)之前還有兩個(gè)函數(shù)在調(diào)用,所以大家平時(shí)認(rèn)為的main函數(shù)就是最初的開始是錯(cuò)誤的哦。

3.esp與ebp如何維護(hù)棧幀

在棧的使用中,是從高地址開始的。其中ebp指向棧底,esp指向棧頂。

在這里插入圖片描述

main函數(shù)被調(diào)用后,程序會(huì)為main函數(shù)分配??臻g。接下來調(diào)試并右擊鼠標(biāo)轉(zhuǎn)到反匯編。可以看到

在這里插入圖片描述

這些代碼的意思是

將ebp的值壓棧,然后將esp賦給ebp,給esp減去0E4h的大小,之后分別將ebx,esi,edi壓棧

壓棧的意思是將元素放到棧頂。在上面調(diào)用堆??梢钥吹絤ain函數(shù)由__tmainCRTStartup調(diào)用。圖解如下:

在這里插入圖片描述

值得一提的是,在棧頂放元素是esp會(huì)自動(dòng)指向新放元素的上方。

在這里插入圖片描述

在這里插入圖片描述


上圖中我們很容易的看出在調(diào)用main函數(shù)是為main函數(shù)開辟的??臻g即棧幀,并且將esp的值給ebp,ebp和esp指向同一塊空間,然后esp變小指向上面的區(qū)域,接下來將ebx,esi,edi壓棧。

在這里插入圖片描述

在這里插入圖片描述

接下來這四句,lea是加載有效地址,從上圖中,我們知道ebp指向的地址,那么edi存放的就是ebp-0E4h的地址也就是③esp處的地址,最后一句rep stos dword ptr es:[edi] 意思是從edi里面重復(fù)拷貝ecx次eax的內(nèi)容。一次拷貝四個(gè)字節(jié),dword是四個(gè)字節(jié)的意思。

在這里插入圖片描述

接下來這三個(gè)匯編代碼的意思就是將值放入相應(yīng)的空間。至于為什么是為什么是ebp-8和ebp-20,這個(gè)和編譯器有關(guān),就不過多敘述。

在這里插入圖片描述

在這里插入圖片描述

由匯編代碼可知,接下來就開始創(chuàng)建形式參數(shù),將要傳遞的參數(shù)值存入eax與ecx這兩個(gè)寄存器中并壓入棧頂,所以創(chuàng)建的形式參數(shù)并不在add函數(shù)的函數(shù)棧幀哦,并且我們之前常說的形參是實(shí)參的一份臨時(shí)拷貝無疑是非常正確的。

在這里插入圖片描述

在這里插入圖片描述

接下來開始add函數(shù)調(diào)用。call是調(diào)用的意思,后面是add函數(shù)的地址用來找到調(diào)用函數(shù)。這里值得一提的是call指令下一條指令的地址被存儲(chǔ)來方便執(zhí)行完add函數(shù)可以跳回來。

Add函數(shù)創(chuàng)建棧幀的過程其實(shí)和main函數(shù)一樣的,先將ebp壓棧方便找到指向main函數(shù)棧底的空間,再將esp的地址存放到ebp里面,此時(shí),esp和ebp指向同一位置,再將esp上移0CCh個(gè)位置,然后就是ebx,esi,edi壓棧,這里不多作說明,由下圖可清晰理解:

在這里插入圖片描述

在這里插入圖片描述

接下來初始化z與執(zhí)行加法也沒什么要說的,z=x=y是找到之前創(chuàng)建的形參來進(jìn)行加法。并將結(jié)果移動(dòng)到z里。

在這里插入圖片描述

返回z的操作是將z的值存放到eax這個(gè)寄存器中,所以函數(shù)銷毀變量與返回的值這個(gè)操作并不沖突。

在這里插入圖片描述

最后銷毀add函數(shù)棧幀,pop就是彈出元素然后把元素放入后面的寄存器,每次pop都會(huì)銷毀一個(gè)棧頂元素然后esp自動(dòng)++往下挪移。三下pop之后要回收空間了,操作是把ebp的值傳給esp這樣esp指向的空間是main函數(shù)的棧頂,然后popebp這個(gè)操作會(huì)將之前棧底存放的之前存放的main函數(shù)的棧底指針傳給ebp,這樣ebp就指向了main函數(shù)的棧底。如下圖:

在這里插入圖片描述

接下來銷毀main函數(shù)的操作也與之前一樣,就不細(xì)說了。

總結(jié) 

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!        

相關(guān)文章

  • C語言使用strcmp()函數(shù)比較兩個(gè)字符串的實(shí)現(xiàn)

    C語言使用strcmp()函數(shù)比較兩個(gè)字符串的實(shí)現(xiàn)

    這篇文章主要介紹了C語言使用strcmp()函數(shù)比較兩個(gè)字符串的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 淺析C++中的間接宏函數(shù)

    淺析C++中的間接宏函數(shù)

    這篇文章主要介紹了C++中的間接宏函數(shù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 解析C++中臨時(shí)對(duì)象的產(chǎn)生情況

    解析C++中臨時(shí)對(duì)象的產(chǎn)生情況

    臨時(shí)對(duì)象的產(chǎn)生和銷毀都是有成本的,都會(huì)影響程序的執(zhí)行性能和效率,所以如果能了解臨時(shí)對(duì)象產(chǎn)生的原因,就可以提升程序的性能和效率,下面小編就來和大家聊聊臨時(shí)對(duì)象產(chǎn)生的幾種情況吧
    2023-06-06
  • 減少C++代碼編譯時(shí)間的簡(jiǎn)單方法(必看篇)

    減少C++代碼編譯時(shí)間的簡(jiǎn)單方法(必看篇)

    下面小編就為大家?guī)硪黄獪p少C++代碼編譯時(shí)間的簡(jiǎn)單方法(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • C++創(chuàng)建多線程的方法總結(jié)

    C++創(chuàng)建多線程的方法總結(jié)

    下個(gè)迭代有個(gè)任務(wù)很有趣,用大量的線程去訪問一個(gè)接口,直至其崩潰為止,這就需要多線程的知識(shí),這也不是什么難事,本文總結(jié)一下C++中的多線程方法std、boost、pthread、windows?api,感興趣的朋友可以參考下
    2024-01-01
  • win10系統(tǒng)VS2019配置點(diǎn)云庫PCL1.12.1的詳細(xì)流程

    win10系統(tǒng)VS2019配置點(diǎn)云庫PCL1.12.1的詳細(xì)流程

    這篇文章主要介紹了win10系統(tǒng)VS2019配置點(diǎn)云庫PCL1.12.1的教程與經(jīng)驗(yàn)總結(jié),本文記錄小白在配置過程中踩過的一些小坑,需要的朋友可以參考下
    2022-07-07
  • C++的虛析構(gòu)詳解及實(shí)例代碼

    C++的虛析構(gòu)詳解及實(shí)例代碼

    這篇文章主要介紹了C++的虛析構(gòu)詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C語言中的鏈接編寫教程

    C語言中的鏈接編寫教程

    這篇文章主要介紹了C語言中的鏈接編寫教程,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-08-08
  • VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析

    VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析

    這篇文章主要介紹了VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析,需要的朋友可以參考下
    2014-08-08
  • C++的繼承特性你了解嗎

    C++的繼承特性你了解嗎

    這篇文章主要為大家詳細(xì)介紹了C++的繼承特性,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評(píng)論