C函數調用過程分析

來源:互聯網
上載者:User

一.環境:

    x86/WinXP/VC 6.0

二.用例:
int swap(int a, int b)
{
 int v;
 v = a;
 a = b;
 b = v;
 return v;
}

void main(void)
{
 int a = 7;
 int b = 10;
 int c = 0;
 c = swap(a,b);
 return;
}

三.分析:
1:    int swap(int a, int b)
2:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
3:        int v;
4:        v = a;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   mov         dword ptr [ebp-4],eax
5:        a = b;
0040103E   mov         ecx,dword ptr [ebp+0Ch]
00401041   mov         dword ptr [ebp+8],ecx
6:        b = v;
00401044   mov         edx,dword ptr [ebp-4]
00401047   mov         dword ptr [ebp+0Ch],edx
7:        return v;
0040104A   mov         eax,dword ptr [ebp-4]
8:    }
0040104D   pop         edi
0040104E   pop         esi
0040104F   pop         ebx
00401050   mov         esp,ebp
00401052   pop         ebp
00401053   ret

swap函數內部參數處理:
  1.將基址指標EBP壓棧;
  2.將堆棧指標ESP拷貝一份到EBP中;
  3.將ESP值減0x44(為了將這68個位元組填充為0xCC);
  4.將EBX/ESI/EDI壓棧;
  5.將EBP-0x44的地址位移量存到目標地址指標EDI;
  6.將計數器ECX置為0x11(即17個整數);
  7.將EDI所開始的大小為17的記憶體空間填充為0xCCCCCCCC;
  
  8.取出堆棧中被壓的a的值(EBP+8所存的值)放到EAX中;
  9.將EAX中的值(參數a的值)賦給到v;
  10.取出堆棧中被壓的b的值(EBP+0CH所存的值)放到ECX中;
  11.將ECX中的值(參數b的值)賦給到a;
  12.取出堆棧中被壓的b的值(EBP-4所存的值)放到EDX中;
  13.將EDX中的值(變數v的值)賦給到a;
  
  14.將傳回值(v的值)拷貝到EAX中;
  
  15.恢複EDI/ESI/EBX;
  16.恢複ESP為EBP(即進入swap時的ESP);
  17.恢複EBP為調用swap前的值;
  18.swap函數返回;

10:   void main(void)
11:   {
00401070   push        ebp
00401071   mov         ebp,esp
00401073   sub         esp,4Ch
00401076   push        ebx
00401077   push        esi
00401078   push        edi
00401079   lea         edi,[ebp-4Ch]
0040107C   mov         ecx,13h
00401081   mov         eax,0CCCCCCCCh
00401086   rep stos    dword ptr [edi]
12:       int a = 7;
00401088   mov         dword ptr [ebp-4],7
13:       int b = 10;
0040108F   mov         dword ptr [ebp-8],0Ah
14:       int c = 0;
00401096   mov         dword ptr [ebp-0Ch],0
15:       c = swap(a,b);
0040109D   mov         eax,dword ptr [ebp-8]
004010A0   push        eax
004010A1   mov         ecx,dword ptr [ebp-4]
004010A4   push        ecx
004010A5   call        @ILT+5(_swap) (0040100a)
004010AA   add         esp,8
004010AD   mov         dword ptr [ebp-0Ch],eax
16:       return;
17:   }
004010B0   pop         edi
004010B1   pop         esi
004010B2   pop         ebx
004010B3   add         esp,4Ch
004010B6   cmp         ebp,esp
004010B8   call        __chkesp (004010e0)
004010BD   mov         esp,ebp
004010BF   pop         ebp
004010C0   ret

15:       c = swap(a,b);
0040109D   mov         eax,dword ptr [ebp-8]
004010A0   push        eax
004010A1   mov         ecx,dword ptr [ebp-4]
004010A4   push        ecx
004010A5   call        @ILT+5(_swap) (0040100a)
004010AA   add         esp,8
004010AD   mov         dword ptr [ebp-0Ch],eax
分析函數swap調用過程:
  1.將參數值b拷到EAX;
  2.將EAX值壓棧;
  3.將參數值a拷到ECX;
  4.將ECX值壓棧;
  5.CALL swap函數
  6.將堆棧指標加8,丟棄堆棧中a,b的值;
  7.將EAX中的傳回值拷貝到變數c;

調用swap時的堆棧情況:

  0012FEC8 | EDI        |<-- ESP (執行到 v = a語句時堆棧指標)
  0012FECC | ESI        |
  0012FED0 | EBX        |
  0012FED4 | 0xCCCCCCCC |
           |     .      |
           |     .      |
           |     .      |
  0012FF14 | 0xCCCCCCCC |
  0012FF18 | EBP        |<-- EBP (執行到 v = a語句時堆棧指標)
  0012FF1C | 0x004010AA | 執行完調用swap後的返回地址
  0012FF20 | ECX        | a的值
  0012FF24 | EAX        | b的值


四.總結:

1.實參壓棧過程是從右至左,然後壓入函數調用後的返回地址;
2.被調用的函數從堆棧中取實參值;
3.如果採用編譯器進行最佳化,那麼被調用的函數內部是從寄存器還是從堆棧中取實參值?具體情況根據CPU架構和參數個數有關(可以繼續分析哦!);
4.如果函數參數個數超過較多(如果超過5個參數),函數參數如何傳遞呢?
5.函數的傳回值一般會存在一個寄存器,如EAX.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.