一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言函數(shù)調(diào)用過程中的內(nèi)存變化解析

電子設(shè)計(jì) ? 來源:TOMORROW 星辰 ? 作者:TOMORROW 星辰 ? 2020-12-11 16:21 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

相信很多編程新手村的同學(xué)們都會(huì)有一個(gè)疑問:C 語言如何調(diào)用函數(shù)的呢?局部變量的作用域?yàn)槭裁磧H限于函數(shù)內(nèi)?這個(gè)調(diào)用不是指C 語言上的函數(shù)調(diào)用的語法,而是在內(nèi)存的視角下,函數(shù)的調(diào)用過程。本文將從C 語言調(diào)用實(shí)例,內(nèi)存視角,反匯編代碼來探討C 語言函數(shù)的調(diào)用過程,也可以說是C 語言函數(shù)調(diào)用過程圖解。通過這個(gè)C 語言函數(shù)調(diào)用過程圖解,同學(xué)們將會(huì)知道,C 語言函數(shù)在調(diào)用時(shí),內(nèi)存空間是怎樣變化的。

要想理解這一個(gè)過程還好涉及到函數(shù)棧幀的概念。函數(shù)棧幀指的是,在調(diào)用函數(shù)時(shí),系統(tǒng)在??臻g中給函數(shù)所分配的一段連續(xù)空間。其中 ebp(棧幀基址指針)則是指明了當(dāng)前函數(shù)的棧幀基地址,對(duì)函數(shù)的資源(局部變量、實(shí)參等)的訪問,都要通過 ebp+offset(偏移量)來進(jìn)行訪問。而 esp 則是棧指針,指示當(dāng)前??臻g棧頂?shù)奈恢谩?/p>

以下代碼即是此次探討 C 語言函數(shù)調(diào)用過程的實(shí)例源碼:

intsubFunc(intabc)
{
intdef=0x9999;
abc=0x8888;
returnabc;
}

int_tmain()
{

subFunc(0x2222);

return0;
}

源碼很簡(jiǎn)單,在一個(gè)主函數(shù)中,調(diào)用一個(gè)帶參數(shù)的子函數(shù)。源碼使用 Visual Studio2010 進(jìn)行調(diào)試,并同時(shí)查看內(nèi)存窗口、反匯編窗口及變量窗口。

進(jìn)入調(diào)試模式,并將斷點(diǎn)定在調(diào)用子函數(shù) subFunc()處,然后運(yùn)行并觀察。

通過觀察窗口,可以知道,此時(shí)還是在執(zhí)行 main 函數(shù),而 ebp(棧幀基址指針)指向的是 0x0073fb64,esp=0x0073fa98。從反匯編代碼可以看到,在調(diào)用函數(shù)前,需要先將參數(shù)壓棧,也就是將實(shí)參存到了 0x0073fa94 處,然后再調(diào)用到子函數(shù)。

進(jìn)入到子函數(shù)時(shí),esp 已經(jīng)變成了 0x0073fa8c,而 0x0073fa90 處存放的是,子函數(shù)執(zhí)行完后返回到 main 函數(shù)中的地址。進(jìn)入到子函數(shù)后,先將 main 函數(shù)的 ebp 壓棧,然后將當(dāng)前棧頂指針的值賦值給 ebp 作為當(dāng)前子函數(shù)的 subFunc()的棧幀基址指針。此時(shí) esp 和 ebp 都變成了 0x0073fa8c。

緊接著,可以看到,esp 一下子被減去了 0x0cch,也就是說??臻g一下子增長(zhǎng)了 0x0cch,并且這段空間全部被賦值為 0xcc。再往下看,可以看到子函數(shù)中的局部變量被分配在了 0x0073fa84 處(因?yàn)樽兞渴?32 位的,然后 CPU 卻是 64 位的,所以空了 32 位不作使用),也就是說,這一段被初始化為 0xcc 的棧空間是被用來給局部變量分配空間的。

接下來再看,在 main 函數(shù)傳遞了一個(gè)實(shí)參 0x2222 給子函數(shù) subFunc 中的形參 abc。在對(duì) abc 進(jìn)行讀寫時(shí),其實(shí)就是在對(duì)前面實(shí)參所被存儲(chǔ)的空間進(jìn)行讀寫,也就是說形參在作為參數(shù)也作為局部變量的同時(shí),它所被分配的內(nèi)存空間是在函數(shù)棧幀基址 ebp 之下。

而子函數(shù)被執(zhí)行完后,返回的過程則是一個(gè)與上面過程相逆的過程。將相應(yīng)的數(shù)據(jù)出棧,恢復(fù) ebp 等信息,釋放子函數(shù)的??臻g,返回到主函數(shù)。所以局部變量的作用域只是在函數(shù)中,當(dāng)函數(shù)被執(zhí)行完返回時(shí),函數(shù)的棧幀都被釋放了,局部變量等數(shù)據(jù)也就沒有了,不存在了,也就是說局部變量的生命周期是與函數(shù)的生命周期等同的。

經(jīng)過以上的 C 語言函數(shù)調(diào)用過程圖解,相信已經(jīng)理解了 C 語言在內(nèi)存中是如何調(diào)用的了。然后可以總結(jié)并得出下面的函數(shù)調(diào)用的棧幀圖解。從函數(shù)調(diào)用的層面看,??臻g是被從下往上一塊一塊地增長(zhǎng)的,并且是后分配的先被釋放,先分配的后被釋放。

編輯:hfy

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3124

    瀏覽量

    75268
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7632

    瀏覽量

    141732
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    C語言使用函數(shù)調(diào)用的知識(shí)點(diǎn)

    C語言使用函數(shù)調(diào)用,我們?cè)偈煜げ贿^了,但是函數(shù)調(diào)用在內(nèi)存
    發(fā)表于 09-07 11:47 ?1042次閱讀

    C語言內(nèi)存知識(shí)總結(jié):memset函數(shù)和calloc函數(shù)

    memset(翻譯:清零)是計(jì)算機(jī)C/C++語言初始化函數(shù)。作用是將某一塊內(nèi)存
    發(fā)表于 10-24 10:40 ?1395次閱讀

    C函數(shù)調(diào)用機(jī)制與棧幀原理詳解

    當(dāng)一個(gè)C函數(shù)調(diào)用時(shí),函數(shù)的參數(shù)如何傳遞、堆棧指針如何變化、棧幀是如何被建立以及如何被消除的,一直缺乏系統(tǒng)性的理解,因此決定花時(shí)間學(xué)習(xí)下
    發(fā)表于 06-08 10:49 ?1993次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>函數(shù)</b><b class='flag-5'>調(diào)用</b>機(jī)制與棧幀原理詳解

    ARM函數(shù)調(diào)用過程說明

    ARM函數(shù)調(diào)用默認(rèn)4個(gè)參數(shù)用R0-R4傳遞,大于4個(gè)用堆棧傳遞,局部變量保存在堆棧,下面以一個(gè)簡(jiǎn)單的函數(shù)來說明這個(gè)過程。先定義
    發(fā)表于 04-26 10:05

    ARMv8的函數(shù)調(diào)用棧是什么意思?調(diào)用棧的內(nèi)存管理是怎樣的

    調(diào)用解析概念: 任意體系結(jié)構(gòu)的CPU,都設(shè)計(jì)了一套通用寄存器、狀態(tài)寄存器及其他控制寄存器,用以維系系統(tǒng)的正常運(yùn)行。函數(shù)調(diào)用過程中,CPU一般都需要處理幾件事情:保存母
    發(fā)表于 05-13 10:36

    C++教程之函數(shù)的遞歸調(diào)用

    C++教程之函數(shù)的遞歸調(diào)用 在執(zhí)行函數(shù) f 的過程中,又要調(diào)用 f
    發(fā)表于 05-15 18:00 ?35次下載

    C語言入門教程-malloc函數(shù)和free函數(shù)

    malloc函數(shù)和free函數(shù) 假設(shè)您的程序在執(zhí)行過程中需要分配一定量的內(nèi)存。您可以隨時(shí)調(diào)用malloc
    發(fā)表于 07-29 11:58 ?4726次閱讀

    系統(tǒng)調(diào)用函數(shù)庫分析及實(shí)例

    作為用戶我們極少接觸系統(tǒng)調(diào)用,但是我們熟悉C 語言,對(duì)庫函數(shù)調(diào)用并不陌生。C
    發(fā)表于 06-23 16:46 ?46次下載
    系統(tǒng)<b class='flag-5'>調(diào)用</b><b class='flag-5'>函數(shù)</b>庫分析及實(shí)例

    使用過程仿真函數(shù)模擬PID控制的過程

    設(shè)定循環(huán)時(shí)間為200ms。例如OB31 2) 在OB31調(diào)用PID函數(shù)PID_compact,然后在全局庫打開庫文件《Sim_controllprocess_V13_SP1》,并
    的頭像 發(fā)表于 05-27 17:31 ?4343次閱讀

    C語言代碼調(diào)用匯編函數(shù)需要注意什么

    來看下混合語言工程,就比如在匯編程序調(diào)用C函數(shù),或者在C
    的頭像 發(fā)表于 11-12 11:04 ?3102次閱讀

    C語言使用函數(shù)調(diào)用在內(nèi)存究竟發(fā)生了什么?

    C語言使用函數(shù)調(diào)用,我們?cè)偈煜げ贿^了,但是函數(shù)調(diào)用在內(nèi)存
    的頭像 發(fā)表于 01-13 14:09 ?1594次閱讀

    RPC如何在遠(yuǎn)程過程中調(diào)用?

    RPC(Remote Procedure Call Protocol)即遠(yuǎn)程過程調(diào)用,也就是調(diào)用函數(shù)是在其它的控制板上運(yùn)行的,不需要理會(huì)底層的通訊協(xié)議。
    的頭像 發(fā)表于 02-07 09:52 ?1168次閱讀
    RPC如何在遠(yuǎn)程<b class='flag-5'>過程中</b><b class='flag-5'>調(diào)用</b>?

    C語言函數(shù)調(diào)用的形式及過程

    C語言函數(shù)調(diào)用時(shí)的數(shù)據(jù)傳遞 在調(diào)用有參函數(shù)時(shí),主調(diào)函數(shù)
    的頭像 發(fā)表于 03-10 14:28 ?2286次閱讀

    什么是函數(shù)調(diào)用?

    函數(shù)調(diào)用,就是使用我們已經(jīng)定義好的函數(shù),或者C語言自帶的庫函數(shù)
    的頭像 發(fā)表于 04-04 17:21 ?6647次閱讀

    EE-128:C語言中的DSP:從C調(diào)用匯編類成員函數(shù)

    電子發(fā)燒友網(wǎng)站提供《EE-128:C語言中的DSP:從C調(diào)用匯編類成員函數(shù).pdf》資料免費(fèi)下載
    發(fā)表于 01-07 13:48 ?0次下載
    EE-128:<b class='flag-5'>C</b><b class='flag-5'>語言</b>中的DSP:從<b class='flag-5'>C</b><b class='flag-5'>調(diào)用</b>匯編類成員<b class='flag-5'>函數(shù)</b>