C/C++中幾種函數調用方式的比較

來源:互聯網
上載者:User
1. cdecl: C的函數預設調用方式, 適用可變參數,這種方式由於是 函數調用者清理堆棧,所以又導致了產生代碼增長(因為每次函數調用之後都是實現清理功能的代碼,如果是函數自己清理,則只需要一份清理代碼就可以了) 2.
stdcall: 
函數清理堆棧,不可用於可變參數。 3.
fastcall:  類似stdcall, 但把因為它是通過寄存器
來傳送參數的(實際上,它用ECX和EDX傳送前兩個單字(DWORD)或更小的參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的記憶體棧 )。  

基於在不同函數調用方式下的彙編產生代碼作比較:(用VS反組譯碼產生,看標紅代碼即可)
int func(int val1,int val2,int val3){int a;a=val1;return a;}b=func(1,2,3);  //調用語句

--------cdecl------------ func: ......... 004113BE  mov         eax,dword ptr [val1]  004113C1  mov         dword ptr [a],eax 

004113C4  mov         eax,dword ptr [a]  ......... 004113CD  
ret         

b=func(1,2,3): 004113FE  push        3     00411400  push        2     00411402  push        1     00411404  call        func (411028h)  00411409  
add         esp,0Ch  0041140C  mov         dword ptr [b],eax 

說明:
cdecl是函數調用者清理參數(add esp,0Ch,把棧指標加3個int長度的位移,實現參數的清理,如果是類對象還要析構) --------cdecl------------ --------stdcall------------ func: ......... 004113BE  mov         eax,dword ptr [val1]  004113C1  mov         dword ptr [a],eax 

004113C4  mov         eax,dword ptr [a]  .........  004113CD  
ret         0Ch  b=func(1,2,3): 004113FE  push        3     00411400  push        2     00411402  push        1     00411404  call        func (411028h)  00411409  mov         dword ptr [b],eax 說明:
stdcall是函數自己清理參數(注意此時堆棧指標esp是指向返回地址的,返回地址下面是參數,指令
ret OCh使
函數返回再給
esp加上3個int長度的位移來清理參數
) --------stdcall------------


--------fastcall------------ func: ......... 004113BF  
pop         ecx
   004113C0  
mov         dword ptr [ebp-14h],edx  004113C3  
mov         dword ptr [ebp-8],ecx  004113C6  mov         eax,dword ptr [val1] //這裡val1==ebp-8 004113C9  mov         dword ptr [a],eax 

004113CC  mov         eax,dword ptr [a]  .........   004113D5  
ret         4  b=func(1,2,3): 0041140E  push        3     00411410  
mov         edx,2  00411415  
mov         ecx,1  0041141A  call        func (4110B4h)  0041141F  mov         dword ptr [b],eax

說明:
fastcall是通過ecx和edx來傳遞前
兩個單字(DWORD)或更小的參數 ,如這裡用ecx傳遞1( mov ecx,1 ),edx傳遞2(mov edx,2 ), 它的棧中參數清理工作是跟stdcall一樣的,只是這裡只需要清理一個參數就可以了(ret   4 ) --------fastcall------------

總結: 1.cdecl和stdcall好理解,如果不需要可變參數的話,stdcall是好的選擇。 2.fastcall的作用有點不好理解,從上面的代碼看,看不出有多麼快速。。
待續。。   

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.