06_函數(shù)調(diào)用過(guò)程(計(jì)算機(jī)科學(xué))

匯編和可執(zhí)行文件

????????前面我們已經(jīng)知道笋轨,匯編約等于機(jī)器碼。源代碼通過(guò)編譯器(也是一個(gè)軟件)進(jìn)行編譯愈捅,得到機(jī)器碼遏考。以后我們統(tǒng)一用匯編代替機(jī)器碼。

編譯

????????編譯器在編譯程序的時(shí)候蓝谨,分為Debug版本和Release版本灌具。編譯器不會(huì)對(duì)Debug版本的程序進(jìn)行優(yōu)化,而編譯器會(huì)對(duì)Release版本的程序進(jìn)行優(yōu)化譬巫。下面是在反匯編的情況下對(duì)Debug版本和Release版本進(jìn)行一下比較咖楣。
源代碼如下所示:

int main()
{
    int iCount = 10;
    double dStep = 0.123;

    return 0;
}

對(duì)應(yīng)的Debug版本匯編代碼如下所示:

int main()
{
000F1A50  push        ebp  
000F1A51  mov         ebp,esp  
000F1A53  sub         esp,0DCh  
000F1A59  push        ebx  
000F1A5A  push        esi  
000F1A5B  push        edi  
000F1A5C  lea         edi,[ebp-0DCh]  
000F1A62  mov         ecx,37h  
000F1A67  mov         eax,0CCCCCCCCh  
000F1A6C  rep stos    dword ptr es:[edi]  
    int iCount = 10;
000F1A6E  mov         dword ptr [iCount],0Ah  
    double dStep = 0.123;
000F1A75  movsd       xmm0,mmword ptr [__real@3fbf7ced916872b0 (0F6CB0h)]  
000F1A7D  movsd       mmword ptr [dStep],xmm0  

    return 0;
000F1A82  xor         eax,eax  
}

對(duì)應(yīng)的Release版本匯編代碼如下所示:

    int iCount = 10;
    double dStep = 0.123;

    return 0;
008B1000  xor         eax,eax  
}

從上面匯編代碼的結(jié)果可以看出,Debug版本的匯編代碼會(huì)將iCount和dStep這兩個(gè)變量轉(zhuǎn)換成匯編代碼芦昔,而Release版本的匯編代碼就會(huì)將iCount和dStep這兩個(gè)變量省略掉诱贿,也就是會(huì)對(duì)源代碼做一些優(yōu)化。并且Debug版本生成的可執(zhí)行文件的大小(本程序?yàn)?5.5KB)相對(duì)于Release版本的可執(zhí)行程序的大兄槭(本程序?yàn)?.00KB)也要大很多料扰。所以我們建議在以后調(diào)試程序的時(shí)候,最好使用Debug版本進(jìn)行編譯焙蹭,這樣編譯器就不會(huì)幫我們優(yōu)化源代碼晒杈。

鏈接

整個(gè)內(nèi)存可以分為四個(gè)區(qū)域,分別為:

  • 棧區(qū)
    棧區(qū)具有可增長(zhǎng)性孔厉。VS為每個(gè)線程默認(rèn)分配1024KB大小的椪辏空間,如果在棧上分配的空間超過(guò)1024KB撰豺,就會(huì)產(chǎn)生棧溢出的錯(cuò)誤粪般。
    棧空間使用的大小由兩個(gè)寄存器來(lái)決定污桦,分別是棧底指針和棧頂指針亩歹,棧空間中的變量在增加時(shí)寡润,棧頂指針就會(huì)一點(diǎn)一點(diǎn)的向上移動(dòng)捆憎,到最后如果這些變量都已經(jīng)沒(méi)有用了,棧頂指針就會(huì)指向棧底指針梭纹,表示原來(lái)的那些變量已經(jīng)是垃圾數(shù)據(jù)了躲惰。
    如果棧空間上存在函數(shù)調(diào)用過(guò)程(棧的回溯功能)变抽,那么還會(huì)有保存棧底指針的變量础拨,具體的這里就先不做詳細(xì)說(shuō)明了。
  • 堆區(qū)
  • 代碼區(qū)
  • 常量區(qū)

這樣劃分的目的是為了我們編寫的程序更加安全绍载。這樣劃分區(qū)域后诡宗,就可以將代碼區(qū)和常量區(qū)設(shè)置為只讀屬性,從而達(dá)到程序中的代碼以及用到的一些常量就不會(huì)被意外的修改击儡,提高了程序在運(yùn)行期間的安全性塔沃。

匯編代碼

匯編指令:
push代表壓棧的操作
pop代表出棧的操作
ebp棧底指針寄存器
esp棧頂指針寄存器
eip程序計(jì)數(shù)器
efl 標(biāo)志寄存器

下面一般作為通用寄存器:
eax 累加寄存器
edi 源寄存器
esi 基址寄存器

下面是在main函數(shù)中只執(zhí)行一句printf("Hello World!")語(yǔ)句時(shí),ebp和esp的一系列值阳谍。

EBP             ESP             OPRATION
009DFA30        009DF964    
                009DF960        offset string "Hello World!" (0A06BCCh)
                009DF95C        00A02093  call        _printf (0A01370h)
                009DF958        00A02900  push        ebp
009DF958                        00A02901  mov         ebp,esp
                009DF880        00A02903  sub         esp,0D8h
                009DF87C        00A02909  push        ebx
                009DF878        00A0290A  push        esi
                009DF874        00A0290B  push        edi
                009DF870        00A0291E  call        __vcrt_va_start_verify_argument_type<char const * const> (0A011CCh)
                009DF874        00A011CC  jmp         __vcrt_va_start_verify_argument_type<char const * const> (0A02170h)
                009DF870        00A0292C  push        eax
                009DF86C        00A0292D  push        0
                009DF868        00A02932  push        ecx
                009DF864        00A02935  push        1
                009DF860        00A02937  call        dword ptr [__imp____acrt_iob_func (0A0A16Ch)]
                009DF85C        53A6D362  push        ebp
                009DF85C        53A6D363  mov         ebp,esp
009DF958        009DF860        53A6D36E  pop         ebp
                009DF864        53A6D36F  ret
                009DF868        00A0293D  add         esp,4
                009DF864        00A02942  call        __RTC_CheckEsp (0A01113h)
                009DF868        
                009DF864        00A02947  push        eax
                009DF860        00A02948  call        __vfprintf_l (0A0136Bh)
                009DF85C        00A019C0  push        ebp
009DF85C                        00A019C1  mov         ebp,esp
                009DF79C        00A019C3  sub         esp,0C0h
                009DF798        00A019C9  push        ebx
                009DF794        00A019CA  push        esi
                009DF790        00A019CB  push        edi
                009DF78C        00A019E3  push        eax
                009DF788        00A019E7  push        ecx
                009DF784        00A019EB  push        edx
                009DF780        00A019EF  push        eax
                009DF77C        00A019F0  call        ___local_stdio_printf_options (0A01339h)
                009DF780        00A01339  jmp         __local_stdio_printf_options (0A02AB0h)
                009DF77C        00A019F8  push        ecx
                009DF778        00A019FB  push        edx
                009DF774        00A019FC  call        dword ptr [__imp____stdio_common_vfprintf (0A0A168h)]
                009DF770        53A67FF2  push        ebp
009DF770                        53A67FF3  mov         ebp,esp
                009DF76C        53A67FF8  push        eax
                009DF768        53A67FFC  push        ecx
                009DF764        53A68000  push        edx
                009DF760        53A68004  push        eax
                009DF75C        53A68008  push        ecx
                009DF758        53A6800C  push        edx
                009DF754        53A6800D  call        53A4CA90
                009DF750        53A4CA92  push        ebp
009DF750                        53A4CA93  mov         ebp,esp
                009DF72C        53A4CA95  sub         esp,24h
                009DF728        53A4CB8A  push        ecx
                009DF724        53A4CB8E  push        edx
                009DF720        53A4CB92  push        eax
                009DF71C        53A4CB96  push        ecx
                009DF718        53A4CB9A  push        edx
                009DF714        53A4CB9E  call        53A20590
                009DF710        53A20592  push        ebp
009DF710                        53A20593  mov         ebp,esp
                009DF70C        53A20595  push        ecx
                009DF710        53A205C8  mov         esp,ebp
009DF750        009DF714        53A205CA  pop         ebp
                009DF72C        ret
                009DF728        53A4CBA3  push        eax
                009DF724        53A4CBA7  push        eax
                009DF72C        53A4CBAD  add         esp,8
                009DF750        53A4CBB0  mov         esp,ebp
009DF770        009DF754        53A4CBB2  pop         ebp
                009DF758        53A4CBB3  ret
                009DF770        53A68012  add         esp,18h
009DF85C        009DF774        53A68015  pop         ebp
                009DF778        53A68016  ret
                009DF790        00A01A02  add         esp,18h
                009DF794        00A01A0C  pop         edi
                009DF798        00A01A0D  pop         esi
                009DF79C        00A01A0E  pop         ebx
                009DF85C        00A01A0F  add         esp,0C0h
                009DF85C        00A01A17  call        __RTC_CheckEsp (0A01113h)
009DF958        009DF860        00A01A1E  pop         ebp
                009DF864        00A01A1F  ret
                009DF874        00A0294D  add         esp,10h
                009DF878        00A0295D  pop         edi
                009DF87C        00A0295E  pop         esi
                009DF880        00A0295F  pop         ebx
                009DF958        00A02960  add         esp,0D8h
                009DF958        00A02968  call        __RTC_CheckEsp (0A01113h)
009DF958        009DF958        00A0296D  mov         esp,ebp
009DFA30        009DF95C        00A0296F  pop         ebp
                009DF960        00A02970  ret
                009DF964        00A02098  add         esp,4
                009DF968        00A0209D  pop         edi
                009DF96C        00A0209E  pop         esi
                009DF970        00A0209F  pop         ebx
                009DFA30        00A020A0  add         esp,0C0h
009DFA44        009DFA34        00A020AF  pop         ebp
                009DFA38        00A020B0  ret
009DFA44                        00A0214E  add         esp,0Ch
009DFA9C        009DFA48        00A02151  pop         ebp
                009DFA4C        00A02152  ret
                009DFA48        00A01FC2  push        ecx
                                00A01FC3  call        _exit (0A012CBh)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛀柴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子矫夯,更是在濱河造成了極大的恐慌鸽疾,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件训貌,死亡現(xiàn)場(chǎng)離奇詭異制肮,居然都是意外死亡冒窍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門豺鼻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)综液,“玉大人,你說(shuō)我怎么就攤上這事儒飒∫馀遥” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵约素,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我笆凌,道長(zhǎng)圣猎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任乞而,我火速辦了婚禮送悔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘爪模。我一直安慰自己欠啤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布屋灌。 她就那樣靜靜地躺著洁段,像睡著了一般。 火紅的嫁衣襯著肌膚如雪共郭。 梳的紋絲不亂的頭發(fā)上祠丝,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音除嘹,去河邊找鬼写半。 笑死,一個(gè)胖子當(dāng)著我的面吹牛尉咕,可吹牛的內(nèi)容都是我干的叠蝇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼年缎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼悔捶!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起晦款,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤炎功,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后缓溅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛇损,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了淤齐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片股囊。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖更啄,靈堂內(nèi)的尸體忽然破棺而出稚疹,到底是詐尸還是另有隱情,我是刑警寧澤祭务,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布内狗,位于F島的核電站,受9級(jí)特大地震影響义锥,放射性物質(zhì)發(fā)生泄漏柳沙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一拌倍、第九天 我趴在偏房一處隱蔽的房頂上張望赂鲤。 院中可真熱鬧,春花似錦柱恤、人聲如沸数初。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)泡孩。三九已至,卻和暖如春荚守,著一層夾襖步出監(jiān)牢的瞬間珍德,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工矗漾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锈候,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓敞贡,卻偏偏與公主長(zhǎng)得像泵琳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子誊役,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容