標(biāo)題: C語(yǔ)言函數(shù)調(diào)用的底層機(jī)制 [打印本頁(yè)] 作者: 51黑tt 時(shí)間: 2016-3-6 00:13 標(biāo)題: C語(yǔ)言函數(shù)調(diào)用的底層機(jī)制 這是一篇介紹C語(yǔ)言中的函數(shù)調(diào)用是如何用實(shí)現(xiàn)的文章。寫給那些對(duì)C語(yǔ)言各種行為的底層實(shí)現(xiàn)感興趣人的入門級(jí)文章。如果你是C語(yǔ)言或者匯編、底層技術(shù)
的老鳥或是對(duì)這個(gè)問(wèn)題不感興趣,那么這篇文章只會(huì)耽誤您的時(shí)間,您大可不必閱讀他。當(dāng)然如果前輩們?cè)敢鉃槲抑赋霾蛔,我將十分感謝您的指導(dǎo),并對(duì)耽誤您寶
貴的時(shí)間致歉。
好了,廢話少說(shuō)!要研究這個(gè)問(wèn)題,讓我們先打開(kāi)VC++吧。最好是6.0的,:-P。(什么你沒(méi)有VC++,倒!....趕快裝一個(gè)!@#$,要快!)
首先,讓我們?cè)赩C++里建立一個(gè)Win32 Console Application項(xiàng)目,并建立主文件fun.c。并輸入以下內(nèi)容。
int fun(int a, int b) {
a = 0x4455;
b = 0x6677;
return a + b;
}
int main() {
fun(0x8899,0x1100);
return 0;
}之
后,最關(guān)鍵的是在項(xiàng)目設(shè)置里關(guān)閉優(yōu)化功能。也就是把Project->Setting->C/C++->Optimizations選
為Disabled。編譯器的優(yōu)化在分析底層實(shí)現(xiàn)時(shí)大多數(shù)情況不太受歡迎。 按鍵盤上的F10鍵,進(jìn)入單步調(diào)試模式(Step
Into)進(jìn)入函數(shù)體。當(dāng)看到那個(gè)黃色的小箭頭指向函數(shù)名的時(shí)候再調(diào)出反匯編窗口(Alt+8)。你會(huì)看到類似下面的代碼: 1: int fun(int a, int b) {
00401000 push ebp
00401001 mov ebp,esp
00401003 sub esp,40h
00401006 push ebx
00401007 push esi
00401008 push edi
00401009 lea edi,[ebp-40h]
0040100C mov ecx,10h
00401011 mov eax,0CCCCCCCCh
00401016 rep stos dword ptr [edi]
2: a = 0x4455;
00401018 mov dword ptr [ebp+8],4455h
3: b = 0x6677;
0040101F mov dword ptr [ebp+0Ch],6677h
4: return a + b;
00401026 mov eax,dword ptr [ebp+8]
00401029 add eax,dword ptr [ebp+0Ch]
5: }
0040102C pop edi
0040102D pop esi
0040102E pop ebx
0040102F mov esp,ebp
00401031 pop ebp
00401032 retVC++就是好,還在難懂的匯編語(yǔ)句前加入了C語(yǔ)言的源代碼。不過(guò)同時(shí)也有不少我們不需要的代碼。因此,你只需要關(guān)心紅色的部分就可以了。
奇怪阿?不是參數(shù)都用push傳遞了嗎?怎么沒(méi)看到被pop出來(lái)?問(wèn)題其實(shí)是這樣,當(dāng)你調(diào)用Call進(jìn)入函數(shù)的時(shí)候Call背著你做了一件事。call把
它下一條語(yǔ)句的地址push進(jìn)了堆棧。(旁人:
什么!這是為什么?)原因很簡(jiǎn)單,因?yàn)楹瘮?shù)調(diào)用完了,要用ret返回。而ret怎么知道返回哪里呢?對(duì)了,