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

C語言詳盡圖解函數(shù)棧幀的創(chuàng)建和銷毀實現(xiàn)

 更新時間:2022年05月06日 14:56:21   作者:利刃Cc  
我們知道c語言中函數(shù)都是被調(diào)用的,main函數(shù)里面能調(diào)用其他函數(shù),其實main函數(shù)也是被別的函數(shù)調(diào)用的,下面通過本文給大家分享c語言函數(shù)棧幀的創(chuàng)建和銷毀過程,一起看看吧

注:本文章所使用的編譯器是VS2010,由于不同編譯器的函數(shù)棧幀與銷毀略有差異,所以具體細節(jié)請讀者自行實踐!

常見寄存器

寄存器有:eax、ebx、ecx、edx、edi、esi、ebp、esp

其中 ebp 和 esp 是用來維護函數(shù)棧幀的,他們里面存放的是地址。

他們維護的是某個正在被調(diào)用的函數(shù)。通常我們又稱 ebp 為棧底指針,稱 esp 為棧頂指針

基本的匯編語言知識

push:壓棧

pop:出棧

mov:若有變量a,b,則把b的值賦給a

ret:返回主程序

call:調(diào)用子程序

add:相加

sub:相減

lea:裝入有效地址

具體實現(xiàn)

我們用一個簡單的例子來展示:

#include<stdio.h>
int Add(int x,int y)
{
    int z=0;
    z=x+y;
    return z;
}
int main()
{
    int a=0;
    int b=20;
    int c=0;
    c=Add(a,b);
    printf("%d\n",c);
    return 0;
}

注:每一個函數(shù)調(diào)用都會在棧區(qū)創(chuàng)建一個空間

我們在這里假設(shè)從下到上是高地址到低地址的方向

通過我們上述介紹的ebp和esp,我們把他們添加上去后的效果則為:

那么有一個問題:main函數(shù)是誰調(diào)用的?

為了解決這個問題,我們打開編譯器然后進行調(diào)試,打開調(diào)用堆棧功能

發(fā)現(xiàn)這里居然有兩個函數(shù),一個是 __tmainCRTStartup(),還有一個是mainCRTStartup()。通過頭文件的查找,發(fā)現(xiàn)了以下的關(guān)系:

main函數(shù)被__tmainCRTStartup()調(diào)用,而__tmainCRTStartup()被mainCRTStartup()調(diào)用。所以,我們在分配空間時,要為__tmainCRTStartup函數(shù)以及mainCRTStartup函數(shù)分配一塊空間。

接下來開始通過反匯編來觀察棧幀空間分配:

通過我們之前的了解,在開辟main之前先開辟了__tmainCRTStartup,所以我們來為其分配空間:

先來看前三步,分別是push:壓棧和mov:賦值和sub:減法

第一步把ebp放到了棧頂,然后在壓棧同時esp會自動向上追蹤棧頂,所以esp向上移動一個,第二步是將esp賦給ebp,所以ebp指針指向棧頂,第三步是esp指針的地址減少0E4h(八進制),所以esp指向了上面某一塊位置,然后將中間這塊空間騰出來讓給了main函數(shù),而開辟的大小取決于編譯器。

效果如下:

接下來push三次

接下來的四步:lea這步操作就是讓[ebp-0E4h]這個值放入edi內(nèi),然后通過觀察我們可以發(fā)現(xiàn),此時放入新值后的edi所指向的就是對應在進行push三個寄存器ebx、esi、edi操作前的esp的位置,然后將39h賦給ecx,0CCCCCCCCh賦給eax,然后第四步就是將edi地址向下的39h個dword中全部放入0CCCCCCCCh。

這些步驟就開辟了main函數(shù)!看接下來的代碼:

將10放到了ebp-8的位置,也就是ebp向上八個字節(jié)的位置,然后將20放到ebp-20的 位置,將0放到ebp-32的位置,如圖:

接下來是add函數(shù)的反匯編代碼:

這里把ebp-20也就是b的值放到了eax中,然后壓棧。接著把ebp-8也就是a 的值放到了ecx中,然后壓棧。

然后就是call就跳到了add這個函數(shù)的地址處去,注意,該處call后進行一個壓棧操作,將add后面一步的地址放在該棧位:

這種做法是為了調(diào)用完add后返回時需要找回原來的地址,所以需要在此處壓一個地址,以便add跳回時尋址,才能往下執(zhí)行。接下來才是add函數(shù)的內(nèi)容:

前幾步的操作是為了給add函數(shù)開辟空間,這和開辟main函數(shù)是一樣的,所以這里略過:

接下來就是將0賦給ebp-8的位置,然后把ebp+8也就是剛才傳參過來的x,放到eax里,然后把ebp+12就是形參y與eax相加,最后把eax放到ebp-8也就是z的位置:

最后看這個:

首先ebp-8也就是z放到eax,這樣子就防止銷毀add后數(shù)據(jù)也沒了。

然后就是edi、esi、ebx的pop,然后把esp移到ebp的位置,最后彈出ebp。

最后是ret。我們知道,當運行完call指令后會跳轉(zhuǎn)到下面的代碼繼續(xù)執(zhí)行,這個時候就可以知道當時存的call指令下一條指令地址的用處了,而ret就是讓其退出后執(zhí)行這一操作的代碼。

ret執(zhí)行完后會pop,于是esp又會+4,向下移動,如圖:

然后回到main函數(shù)

繼續(xù)執(zhí)行以下步驟將eax里面的值(就是之前算出的30),mov放入到[ebp-20h]的位置里(也就是放入c中)。

接下來程序運行完后就是main函數(shù)的銷毀,與之前Add函數(shù)銷毀步驟大致相同,就不再贅述了。

關(guān)于棧幀創(chuàng)建與銷毀的問答題

到此這篇關(guān)于C語言詳盡圖解函數(shù)棧幀的創(chuàng)建和銷毀實現(xiàn)的文章就介紹到這了,更多相關(guān)C語言函數(shù)棧幀內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++面試題之結(jié)構(gòu)體內(nèi)存對齊計算問題總結(jié)大全

    C++面試題之結(jié)構(gòu)體內(nèi)存對齊計算問題總結(jié)大全

    這篇文章主要給大家總結(jié)了關(guān)于C++面試題中結(jié)構(gòu)體內(nèi)存對齊計算問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,通過這些介紹的內(nèi)容對大家在面試C++工作的時候,會有一定的參考幫助,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-08-08
  • C語言員工信息管理系統(tǒng)源代碼

    C語言員工信息管理系統(tǒng)源代碼

    這篇文章主要為大家詳細介紹了C語言員工信息管理系統(tǒng)源代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C++ COM編程之什么是組件?

    C++ COM編程之什么是組件?

    這篇文章主要介紹了COM編程之什么是組件?COM組件是以Win32動態(tài)鏈接庫(DLLs)或可執(zhí)行文件(EXEs)的形式發(fā)布的可執(zhí)行代碼,需要的朋友可以參考下
    2014-10-10
  • 使用C語言實現(xiàn)vector動態(tài)數(shù)組的實例分享

    使用C語言實現(xiàn)vector動態(tài)數(shù)組的實例分享

    vector是指能夠存放任意類型的動態(tài)數(shù)組,而C語言中并沒有面向?qū)ο蟮腃++那樣內(nèi)置vector類,所以我們接下來就來看一下使用C語言實現(xiàn)vector動態(tài)數(shù)組的實例,需要的朋友可以參考下
    2016-05-05
  • C基礎(chǔ) mariadb處理的簡單實例

    C基礎(chǔ) mariadb處理的簡單實例

    下面小編就為大家?guī)硪黄狢基礎(chǔ) mariadb處理的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • C++與Lua交互內(nèi)存分配詳解

    C++與Lua交互內(nèi)存分配詳解

    C/C++ 與 Lua 的交互是通過 lua_State 這一句柄進行交互,我們常規(guī)的創(chuàng)建都是通過 luaL_newstate 這一輔助函數(shù),這篇文章主要給大家詳細介紹了C++與Lua交互內(nèi)存分配,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2023-11-11
  • 深入理解C++內(nèi)鏈接與外鏈接的意義

    深入理解C++內(nèi)鏈接與外鏈接的意義

    鏈接描述了名稱在整個程序或一個翻譯單元中如何引用或不引用同一實體,下面這篇文章主要給大家介紹了關(guān)于C++內(nèi)鏈接與外鏈接意義的理解,需要的朋友可以參考下
    2021-11-11
  • C語言經(jīng)典例程100例(經(jīng)典c程序100例)

    C語言經(jīng)典例程100例(經(jīng)典c程序100例)

    這篇文章主要介紹了C語言經(jīng)典例程100例,經(jīng)典c程序100例,學習c語言的朋友可以參考一下
    2018-03-03
  • 深入理解C/C++混合編程

    深入理解C/C++混合編程

    本篇文章是對C/C++混合編程進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • websocket++簡單使用及實例分析

    websocket++簡單使用及實例分析

    下面小編就為大家?guī)硪黄獁ebsocket++簡單使用及實例分析。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05

最新評論