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

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

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

前言

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

以上這些都可以通過(guò)了解函數(shù)棧幀的創(chuàng)建與銷毀來(lái)理解。接下來(lái)我就帶大家來(lái)了解函數(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è)地址使用來(lái)維護(hù)函數(shù)棧幀的。每一個(gè)函數(shù)調(diào)用,都要在棧區(qū)創(chuàng)建一個(gè)空間,這塊空間叫做函數(shù)棧幀,用esp與ebp來(lái)維護(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ù),不用多說(shuō)。

2.調(diào)用堆棧

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

在這里插入圖片描述

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

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

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

在這里插入圖片描述

main函數(shù)被調(diào)用后,程序會(huì)為main函數(shù)分配棧空間。接下來(lái)調(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ù)開(kāi)辟的棧空間即棧幀,并且將esp的值給ebp,ebp和esp指向同一塊空間,然后esp變小指向上面的區(qū)域,接下來(lái)將ebx,esi,edi壓棧。

在這里插入圖片描述

在這里插入圖片描述

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

在這里插入圖片描述

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

在這里插入圖片描述

在這里插入圖片描述

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

在這里插入圖片描述

在這里插入圖片描述

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

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

在這里插入圖片描述

在這里插入圖片描述

接下來(lái)初始化z與執(zhí)行加法也沒(méi)什么要說(shuō)的,z=x=y是找到之前創(chuàng)建的形參來(lái)進(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ù)的棧底。如下圖:

在這里插入圖片描述

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

總結(jié) 

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

相關(guān)文章

  • C語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn)通訊錄管理系統(tǒng)

    C語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn)通訊錄管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn)通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 用C語(yǔ)言實(shí)現(xiàn)井字棋游戲代碼

    用C語(yǔ)言實(shí)現(xiàn)井字棋游戲代碼

    大家好,本篇文章主要講的是用C語(yǔ)言實(shí)現(xiàn)井字棋游戲代碼,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C中實(shí)現(xiàn)矩陣乘法的一種高效的方法

    C中實(shí)現(xiàn)矩陣乘法的一種高效的方法

    本篇文章介紹了,在C中實(shí)現(xiàn)矩陣乘法的一種高效的方法。需要的朋友參考下
    2013-05-05
  • 在C語(yǔ)言中輸入中文字符串講解

    在C語(yǔ)言中輸入中文字符串講解

    這篇文章主要介紹了在C語(yǔ)言中輸入中文字符串講解,本文通過(guò)概念和案例相結(jié)合講述了如何在C語(yǔ)言中使用中文,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 簡(jiǎn)單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)

    簡(jiǎn)單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)

    桶排序是將要排序的算法按桶分組排序之后再遍歷匯總的一種線性排序算法,下面就讓我們來(lái)通過(guò)小例子簡(jiǎn)單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)^^
    2016-07-07
  • c語(yǔ)言操作文本的基本使用方法

    c語(yǔ)言操作文本的基本使用方法

    這篇文章主要介紹了c語(yǔ)言操作文本的基本使用方法,需要的朋友可以參考下
    2014-04-04
  • 深入理解Qt信號(hào)槽機(jī)制

    深入理解Qt信號(hào)槽機(jī)制

    信號(hào)槽是 Qt 框架引以為豪的機(jī)制之一。本文主要介紹了Qt信號(hào)槽機(jī)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語(yǔ)言詳細(xì)講解if語(yǔ)句與switch語(yǔ)句的用法

    C語(yǔ)言詳細(xì)講解if語(yǔ)句與switch語(yǔ)句的用法

    用 if 語(yǔ)句可以構(gòu)成分支結(jié)構(gòu),它根據(jù)給的條件進(jìn)行判定,以決定執(zhí)行哪個(gè)分支程序段,C 語(yǔ)言中還有另外一種分支語(yǔ)句,就是 switch 語(yǔ)句
    2022-05-05
  • C++17結(jié)構(gòu)化綁定的實(shí)現(xiàn)

    C++17結(jié)構(gòu)化綁定的實(shí)現(xiàn)

    這篇文章主要介紹了C++17結(jié)構(gòu)化綁定的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • C語(yǔ)言動(dòng)態(tài)規(guī)劃之背包問(wèn)題詳解

    C語(yǔ)言動(dòng)態(tài)規(guī)劃之背包問(wèn)題詳解

    這篇文章主要介紹了C語(yǔ)言動(dòng)態(tài)規(guī)劃之背包問(wèn)題詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評(píng)論

施甸县| 罗江县| 水富县| 昭通市| 万宁市| 黔南| 图木舒克市| 苏尼特右旗| 屏南县| 遂溪县| 珠海市| 安仁县| 伊金霍洛旗| 营口市| 巴中市| 犍为县| 称多县| 黄梅县| 吴堡县| 三门峡市| 临泉县| 城口县| 山东省| 成都市| 栾城县| 和林格尔县| 内江市| 金寨县| 肥西县| 渑池县| 德化县| 乐至县| 隆化县| 北流市| 京山县| 拜城县| 锦屏县| 兖州市| 临沭县| 南城县| 承德县|