標題: C語言函數調用的底層機制 [打印本頁] 作者: 51黑tt 時間: 2016-3-6 00:13 標題: C語言函數調用的底層機制 這是一篇介紹C語言中的函數調用是如何用實現的文章。寫給那些對C語言各種行為的底層實現感興趣人的入門級文章。如果你是C語言或者匯編、底層技術
的老鳥或是對這個問題不感興趣,那么這篇文章只會耽誤您的時間,您大可不必閱讀他。當然如果前輩們愿意為我指出不足,我將十分感謝您的指導,并對耽誤您寶
貴的時間致歉。
好了,廢話少說!要研究這個問題,讓我們先打開VC++吧。最好是6.0的,:-P。(什么你沒有VC++,倒!....趕快裝一個!@#$,要快!)
首先,讓我們在VC++里建立一個Win32 Console Application項目,并建立主文件fun.c。并輸入以下內容。
int fun(int a, int b) {
a = 0x4455;
b = 0x6677;
return a + b;
}
int main() {
fun(0x8899,0x1100);
return 0;
}之
后,最關鍵的是在項目設置里關閉優化功能。也就是把Project->Setting->C/C++->Optimizations選
為Disabled。編譯器的優化在分析底層實現時大多數情況不太受歡迎。 按鍵盤上的F10鍵,進入單步調試模式(Step
Into)進入函數體。當看到那個黃色的小箭頭指向函數名的時候再調出反匯編窗口(Alt+8)。你會看到類似下面的代碼: 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++就是好,還在難懂的匯編語句前加入了C語言的源代碼。不過同時也有不少我們不需要的代碼。因此,你只需要關心紅色的部分就可以了。
奇怪阿?不是參數都用push傳遞了嗎?怎么沒看到被pop出來?問題其實是這樣,當你調用Call進入函數的時候Call背著你做了一件事。call把
它下一條語句的地址push進了堆棧。(旁人:
什么!這是為什么?)原因很簡單,因為函數調用完了,要用ret返回。而ret怎么知道返回哪里呢?對了,