_cdecl和__stdcall修飾對比

來源:互聯網
上載者:User

_cdecl和__stdcall修飾對比

由_cdecl和__stdcall修飾的函數在被調用的時候的差別。
兩個都是函數參數從右至左入棧,但是有細微的差別。
_cdecl修飾的函數,它的參數所佔用的堆棧是由調用函數去清空的。
__stdcall修飾的函數,它的參數所佔用的堆棧是由被調用的函數自己返回的時候清空的。

 

寫一個簡單的程式,查看彙編代碼進行對比。

#include "stdafx.h"</p><p>int_cdecladd1(int a, int b)<br />{<br />return a+b;<br />}<br />///////////////////////////////////////////////////////////////////////////////<br />int__stdcalladd2(int a, int b)<br />{<br />return a+b;<br />}<br />///////////////////////////////////////////////////////////////////////////////<br />int main(int argc, char* argv[])<br />{<br />int a, b, c;<br />a = 12;<br />b = 18;<br />c = add1(a, b);<br />c = add2(a, b);<br />return 0;<br />}

TITLEF:/SourceCode/VC/Test/Test.cpp<br />.386P<br />include listing.inc<br />if @Version gt 510<br />.model FLAT<br />else<br />_TEXTSEGMENT PARA USE32 PUBLIC 'CODE'<br />_TEXTENDS<br />_DATASEGMENT DWORD USE32 PUBLIC 'DATA'<br />_DATAENDS<br />CONSTSEGMENT DWORD USE32 PUBLIC 'CONST'<br />CONSTENDS<br />_BSSSEGMENT DWORD USE32 PUBLIC 'BSS'<br />_BSSENDS<br />$$SYMBOLSSEGMENT BYTE USE32 'DEBSYM'<br />$$SYMBOLSENDS<br />$$TYPESSEGMENT BYTE USE32 'DEBTYP'<br />$$TYPESENDS<br />_TLSSEGMENT DWORD USE32 PUBLIC 'TLS'<br />_TLSENDS<br />;COMDAT ?add1@@YAHHH@Z<br />_TEXTSEGMENT PARA USE32 PUBLIC 'CODE'<br />_TEXTENDS<br />;COMDAT ?add2@@YGHHH@Z<br />_TEXTSEGMENT PARA USE32 PUBLIC 'CODE'<br />_TEXTENDS<br />;COMDAT _main<br />_TEXTSEGMENT PARA USE32 PUBLIC 'CODE'<br />_TEXTENDS<br />FLATGROUP _DATA, CONST, _BSS<br />ASSUMECS: FLAT, DS: FLAT, SS: FLAT<br />endif<br />PUBLIC?add1@@YAHHH@Z; add1<br />;COMDAT ?add1@@YAHHH@Z<br />_TEXTSEGMENT<br />_a$ = 8<br />_b$ = 12<br />?add1@@YAHHH@Z PROC NEAR; add1, COMDAT</p><p>; 7 : {</p><p>pushebp<br />movebp, esp<br />subesp, 64; 00000040H<br />pushebx<br />pushesi<br />pushedi<br />leaedi, DWORD PTR [ebp-64]<br />movecx, 16; 00000010H<br />moveax, -858993460; ccccccccH<br />rep stosd</p><p>; 8 : return a+b;</p><p>moveax, DWORD PTR _a$[ebp]<br />addeax, DWORD PTR _b$[ebp]</p><p>; 9 : }</p><p>popedi<br />popesi<br />popebx<br />movesp, ebp<br />popebp<br />ret0;這裡是_cdecl修飾的函數。函數執行完直接退出,並沒有釋放參數所點的堆棧<br />?add1@@YAHHH@Z ENDP; add1<br />_TEXTENDS<br />PUBLIC?add2@@YGHHH@Z; add2<br />;COMDAT ?add2@@YGHHH@Z<br />_TEXTSEGMENT<br />_a$ = 8<br />_b$ = 12<br />?add2@@YGHHH@Z PROC NEAR; add2, COMDAT</p><p>; 12 : {</p><p>pushebp<br />movebp, esp<br />subesp, 64; 00000040H<br />pushebx<br />pushesi<br />pushedi<br />leaedi, DWORD PTR [ebp-64]<br />movecx, 16; 00000010H<br />moveax, -858993460; ccccccccH<br />rep stosd</p><p>; 13 : return a+b;</p><p>moveax, DWORD PTR _a$[ebp]<br />addeax, DWORD PTR _b$[ebp]</p><p>; 14 : }</p><p>popedi<br />popesi<br />popebx<br />movesp, ebp<br />popebp<br /><span style="color: #ff0000;" mce_style="color: #ff0000;">ret8;ret 8=ret && add esp,8。這裡是__stdcall所修飾的函數,返回時清空參數所佔的堆棧空間</style><br />?add2@@YGHHH@Z ENDP; add2<br />_TEXTENDS<br />PUBLIC_main<br />EXTRN__chkesp:NEAR<br />;COMDAT _main<br />_TEXTSEGMENT<br />_a$ = -4<br />_b$ = -8<br />_c$ = -12<br />_mainPROC NEAR; COMDAT</p><p>; 17 : {</p><p>pushebp<br />movebp, esp<br />subesp, 76; 0000004cH<br />pushebx<br />pushesi<br />pushedi<br />leaedi, DWORD PTR [ebp-76]<br />movecx, 19; 00000013H<br />moveax, -858993460; ccccccccH<br />rep stosd</p><p>; 18 : int a, b, c;<br />; 19 : a = 12;</p><p>movDWORD PTR _a$[ebp], 12; 0000000cH</p><p>; 20 : b = 18;</p><p>movDWORD PTR _b$[ebp], 18; 00000012H</p><p>; 21 : c = add1(a, b);</p><p>;調用函數參數入棧<br />moveax, DWORD PTR _b$[ebp]<br />pusheax<br />movecx, DWORD PTR _a$[ebp]<br />pushecx<br />call?add1@@YAHHH@Z; add1<br />addesp, 8;_cdecl修飾的需要在調用函數結束之後,對參數所佔的堆棧空間進行清空。<br />movDWORD PTR _c$[ebp], eax</p><p>; 22 : c = add2(a, b);</p><p>movedx, DWORD PTR _b$[ebp]<br />pushedx<br />moveax, DWORD PTR _a$[ebp]<br />pusheax<br />call?add2@@YGHHH@Z; add2<br />;__stdcall修飾函數在返回的時候,參數所佔的堆棧空間已經由被調用函數返回時清空。<br />movDWORD PTR _c$[ebp], eax</p><p>; 23 : return 0;</p><p>xoreax, eax</p><p>; 24 : }</p><p>popedi<br />popesi<br />popebx<br />addesp, 76; 0000004cH<br />cmpebp, esp<br />call__chkesp<br />movesp, ebp<br />popebp<br />ret0<br />_mainENDP<br />_TEXTENDS<br />END<br />

聯繫我們

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