一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

函數(shù)調(diào)用時(shí)的??臻g變化

 曉理曉章 2017-02-16
  1.   
  1. </pre><pre name="code" class="cpp">#include <stdio.h>  
  2.   
  3. int fun2(int x, int y, int z)  
  4. {  
  5.     int i = x + y;  
  6.     int j = y + z;  
  7.     int k = i + j;  
  8.     return k;  
  9. }  
  10.   
  11. int fun1(int a, int b)  
  12. {  
  13.     int c = a + b;  
  14.     int d = 0;  
  15.     d = fun2(a, b, c);  
  16.     return d;  
  17. }  
  18.   
  19. int main()  
  20. {  
  21.     int num1 = 10;  
  22.     int num2 = 20;  
  23.   
  24.     fun1(num1, num2);  
  25.     return 0;  
  26. }  

以上邊代碼為例,main函數(shù)調(diào)用了fun1函數(shù), 而fun1函數(shù)又調(diào)用了fun2函數(shù)。在調(diào)用過(guò)程中??臻g的變化如下



在fun1調(diào)用前 目前是main函數(shù)的??臻gnum1變量已經(jīng)賦值為10, num2變量賦值為20;

ESP 是棧指針寄存器這個(gè)寄存器中存儲(chǔ)著棧頂?shù)牡刂贰?EBP中存儲(chǔ)著棧底的地址。 函數(shù)??臻g主要是由這兩個(gè)寄存器來(lái)確定


main函數(shù)調(diào)用fun1函數(shù)時(shí),第1 步操作就是把傳入的參數(shù)壓入到棧中。 C語(yǔ)言使用的是_cdecl調(diào)用方式,參數(shù)從右向左依次壓入棧中
所以實(shí)參num2的數(shù)值被復(fù)制到了形參b所在的內(nèi)存中



接著又將實(shí)參num1的數(shù)值復(fù)制到了形參a所在的內(nèi)存中。ESP的數(shù)值也隨著不斷減小以指向棧頂


調(diào)用函數(shù)結(jié)束后都會(huì)返回到代碼所調(diào)用行的下一行繼續(xù)執(zhí)行。那么他是怎樣知道返回后要繼續(xù)執(zhí)行哪塊地址上的命令呢。參數(shù)壓入??臻g后,接下來(lái)的工作就是保存被調(diào)用函數(shù)返回后要執(zhí)行指令的地址。也就是保存到當(dāng)前ESP所指向的??臻g中


再接下來(lái),保存當(dāng)前函數(shù)的棧底到ESP所指向內(nèi)存中去。



提升棧底,此時(shí) ESP 和EBP都指向相同地址


ESP減8, 我們已經(jīng)為fun1的兩個(gè)形參分配完了內(nèi)存空間。通過(guò)代碼我們看到,fun1中有兩個(gè)局部變量c和d 。所以ESP減8的目的就是為我們的局部變量分配空間


而在fun1函數(shù)中我們又調(diào)用了fun2函數(shù),fun2函數(shù)的調(diào)用過(guò)程與fun1類(lèi)似

        

         

在fun2函數(shù)中,k運(yùn)算得80; 函數(shù)返回語(yǔ)句 return k;我們要返回k的值,可是當(dāng)我們退出函數(shù)后,顯然fun2的??臻g已經(jīng)不再有效,那么他是怎么把這個(gè)80傳遞到fun1中去的呢
計(jì)算機(jī)中存儲(chǔ)數(shù)據(jù)的不僅僅有內(nèi)存。CPU中也有若干用來(lái)存儲(chǔ)數(shù)據(jù)的空間,稱(chēng)之為寄存器。所以在函數(shù)退出之前都會(huì)把結(jié)果保存到這些寄存器當(dāng)中。32位CPU的通用寄存自然最多也只有32位了,64位CPU的通用寄存器最多也只有64位。所以函數(shù)參數(shù)傳遞通常為基本數(shù)據(jù)類(lèi)型或指針。因?yàn)檫@些數(shù)據(jù)的寬度都沒(méi)有超過(guò)寄存器的最大位寬。當(dāng)我們向函數(shù)中傳遞一個(gè)結(jié)構(gòu)體或類(lèi)時(shí),這個(gè)過(guò)程是一個(gè)數(shù)據(jù)復(fù)制的過(guò)程,如果結(jié)構(gòu)體或類(lèi)成員較多,復(fù)制過(guò)程肯定會(huì)消耗更多的空間和時(shí)間。當(dāng)返回一個(gè)結(jié)構(gòu)體或類(lèi)對(duì)象時(shí),同樣會(huì)產(chǎn)生數(shù)據(jù)復(fù)制的過(guò)程。所以編程中通常是不會(huì)這樣做的,而只需要傳遞一個(gè)結(jié)構(gòu)體指針或類(lèi)對(duì)象地址。只需要簡(jiǎn)單傳遞32位或64位的地址,一切問(wèn)題都可以得到解決。提高程序運(yùn)行效率,節(jié)省空間。這也是指針之所以強(qiáng)大高效的原因之一。
函數(shù)調(diào)用??臻g變化 我們已經(jīng)基本了解了,接下來(lái)再看下,函數(shù)退出時(shí)棧的變化



ESP-0xC 此時(shí)ESP和EBP指向相同地址,當(dāng)前地址內(nèi)存中存放的是前一個(gè)函數(shù)的EBP地址


恢復(fù)原來(lái)EBP的數(shù)值


恢復(fù)EIP的值為00401232 也就是告訴CPU回到調(diào)用fun2函數(shù)之前的函數(shù)中繼續(xù)執(zhí)行下一行代碼


徹底恢復(fù)到fun1的棧空間。 fun2的棧空間不再有效。 函數(shù)退出后原來(lái)使用的數(shù)值計(jì)算機(jī)并沒(méi)有做多余的回收工作。just leave it alone.
所以你不應(yīng)該返回一個(gè)函數(shù)局部變量的指針。當(dāng)退出函數(shù)后這部分空間是不可控制的。因?yàn)樵诤筮叺拇a很 可能又調(diào)用了其它函數(shù),重新使用了fun2所使用過(guò)的??臻g。這時(shí)你用指針操作這塊空間得到的是一個(gè)未知的數(shù)值。這個(gè)數(shù)值是不確定的。也就行成了野指針。還有局部變量的作用域也是由于這個(gè)原因。局部變量和參數(shù)只在當(dāng)前函數(shù)內(nèi)有效。退出后就無(wú)法也不應(yīng)該再繼續(xù)使用。


還記得 大明湖畔的 return k嗎?  d = fun2(a, b, c);  相當(dāng)于  d = k;  
這個(gè)時(shí)候不再是把k的值復(fù)制給d了,fun2函數(shù)已經(jīng)退出,同樣他的??臻g不再有效。在 fun2退出時(shí)k的值是復(fù)制到了寄存器eax中的,所以這時(shí)的d的數(shù)值是從寄存器eax中取得的。

接下來(lái)fun1運(yùn)行完成退出過(guò)程類(lèi)似fun2

      

    

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    99视频精品免费视频| 国产成人精品一区二区三区| 开心五月激情综合婷婷色| 翘臀少妇成人一区二区| 女人精品内射国产99| 精品偷拍一区二区三区| 亚洲中文字幕人妻av| 免费高清欧美一区二区视频| 日韩欧美第一页在线观看| 91香蕉视频精品在线看| 亚洲精品成人福利在线| 好吊日在线视频免费观看| 夫妻性生活真人动作视频| 亚洲一区二区精品福利| 日韩黄色一级片免费收看| 99国产高清不卡视频| 久草视频在线视频在线观看| 国产91麻豆精品成人区| 久久精品国产亚洲av久按摩| 精品国产日韩一区三区| 色好吊视频这里只有精| 欧洲一区二区三区蜜桃| 亚洲国产成人久久一区二区三区 | 国产成人国产精品国产三级| 亚洲一区二区欧美在线| 精品人妻一区二区三区在线看| 精品人妻一区二区四区| 富婆又大又白又丰满又紧又硬| 精品欧美日韩一二三区| 国产成人免费激情视频| 超薄肉色丝袜脚一区二区| 国产精品欧美在线观看| 国产精品久久精品毛片| 日系韩系还是欧美久久| 日本欧美一区二区三区就 | 午夜小视频成人免费看| 欧美大黄片在线免费观看| 六月丁香六月综合缴情| 亚洲欧洲在线一区二区三区| 午夜国产精品国自产拍av| 很黄很污在线免费观看|