Comparison between _ cdecl and _ stdcall
Differences between functions modified by _ cdecl and _ stdcall when called.
Both are function parameters from right to left, but there are slight differences.
_ Cdecl: the stack occupied by its parameters is cleared by calling the function.
_ Stdcall: the stack occupied by its parameters is cleared when the called function returns it.
Write a simple program and view the assembly code for comparison.
# Include "stdafx. H "</P> <p> int_cdecladd1 (int A, int B) <br/> {<br/> return A + B; <br/>}< br/> /////////////////////////////// //////////////////////////////////////// /// // <br/> int _ stdcalladd2 (int, 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. CPP <br/>. 386 P <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 'bsss' <br/> _ bssends <br/> $ symbolssegment byte use32 'destsym' <br />$ $ Symbolsends <br/> $ typessegment byte use32 'descrip' <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; 00000040 H <br/> pushebx <br/> pushesi <br/> pushedi <br/> leaedi, dword ptr [ebp-64] <br/> movecx, 16; 00000010 H <br/> moveax,-858993460; cccccch <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; here is the function modified by _ cdecl. The function exits directly after execution, and the stack specified by the parameter is not released <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; 00000040 H <br/> pushebx <br/> pushesi <br/> pushedi <br/> leaedi, dword ptr [ebp-64] <br/> movecx, 16; 00000010 H <br/> moveax,-858993460; cccccch <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. Here is the function modified by _ stdcall. The stack space occupied by the return parameter is cleared </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; 2017004ch <br/> pushebx <br/> pushesi <br/> pushedi <br/> leaedi, dword ptr [ebp-76] <br/> movecx, 19; 00000013 H <br/> moveax,-858993460; cccccch <br/> r EP 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; 00000012 H </P> <p>; 21: c = Add1 (A, B ); </P> <p>; call function parameters to stack <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: After the function is called, The stack space occupied by the parameter must be cleared. <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/> ;__ when the stdcall modifier function returns, the stack space occupied by the parameter has been cleared when the function is returned. <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; 2017004ch <br/> cmpebp, esp <br/> call _ chkesp <br/> movesp, EBP <br/> popebp <br/> ret0 <br/> _ mainendp <br/> _ textends <br/> end <br/>