_ Stdcall and _ cdecl function calls are different, __stdcall _ cdecl
Refer:
Http://blog.csdn.net/hudashi/article/details/7820338
Http://shitou7630.blog.163.com/blog/static/32699536201342110155436/
Http://www.cnblogs.com/52yixin/archive/2011/06/29/2093634.html
Http://blog.csdn.net/mniwc/article/details/7993361
Http://www.cnblogs.com/coderzh/archive/2008/12/01/1345053.html
Http://blog.sina.com.cn/s/blog_6f6769b50100uhzz.html
Https://msdn.microsoft.com/zh-cn/library/ms235286.aspx
(Owed by: spring night rain http://blog.csdn.net/chunyexiyu reprint please indicate the source)
ESP is the top Pointer Extended Stack Pointer.
EBP is the Base address Pointer Extend Base Pointer
ESP is the pointer that always points to the top of the stack, while EBP is only used to access the top pointer of the stack at a certain time point to facilitate stack operations.
L (under win32) use the _ stdcall Function Definition and function Translation
Void _ stdcall TestCall (int a, int B) { Return; } Run TestCall (1, 2 ); |
Use _ stdcall function Translation: (go to the Disassembly window during execution)
TestCall (1, 2 ); 00F013FE push 2 00F01400 push 1 00F01402 call TestCall (0F01177h) Void _ stdcall TestCall (int a, int B) { Return; } 00F013B0 push ebp // pressure Stack 00F013B1 mov ebp, esp // save esp to ebp 00F013B3 sub esp, 0C0h 00F013B9 push ebx 00F013BA push esi 00F013BB push edi 00F013BC lea edi, [ebp-0C0h] 00F013C2 mov ecx, 30 h 00F013C7 mov eax, 0 CCCCCCCCh 00F013CC rep stos dword ptr es: [edi] 00F013CE pop edi 00F013CF pop esi 00F013D0 pop ebx 00F013D1 mov esp, ebp // restore esp from ebp 00F013D3 pop ebp // restore ebp from the stack 00F013D4 ret 8 // return and unstack 8 bytes, equivalent to add esp, 8; ret; |
(Note: The esp address becomes smaller when the stack is pressed, and the esp address becomes larger when the stack is output, because it is allocated from the back to the back .)
L (under win32) Use _ cdecl or the default Function Definition and function Translation
Void _ stdcall TestCall (int a, int B) { Return; } Run TestCall (1, 2 ); |
Use _ cdecl or the default function Translation: (go to the "disassembly" window during execution)
TestCall (1, 2 ); 012B13FE push 2 012B1400 push 1 012B1402 call TestCall (12B11D6h) 012B1407 add esp, 8 // esp stack back 8 bytes, push 2; push 1; the 8 bytes pushed out. Void TestCall (int a, int B) { Return; } 00F013B0 push ebp // pressure Stack 00F013B1 mov ebp, esp // save esp to ebp 00F013B3 sub esp, 0C0h 00F013B9 push ebx 00F013BA push esi 00F013BB push edi 00F013BC lea edi, [ebp-0C0h] 00F013C2 mov ecx, 30 h 00F013C7 mov eax, 0 CCCCCCCCh 00F013CC rep stos dword ptr es: [edi] 00F013CE pop edi 00F013CF pop esi 00F013D0 pop ebx 00F013D1 mov esp, ebp // restore esp from ebp 00F013D3 pop ebp // restore ebp from the stack 00F013D4 ret // return directly without performing the rollback operation |
(Under win32) Comparison between the two
We can see from the above
If _ stdcall is used, the call side applies the stack function parameter from right to left, but does not return the stack. Function rollback is required.
(Ret 8 -- esp stack rollback 8 bytes)
When _ cdecl is used, the call side presses the stack function parameter from right to left, and after the call, the call side actively performs stack rollback (add esp, 8 -- esp 8 bytes)
L no need to roll back the stack
In some cases, because you do not need to roll back the stack, no error will be reported when you call functions declared by others.
No Parameters:
In this case, the call side does not have the stack function parameter pressure, so there is no function parameter rollback problem, the stack rollback only needs to return 0 Length
When the number of parameters is less than four, the stack is not pressed in the case of winX64 bits:
Refer:
Https://msdn.microsoft.com/zh-cn/library/ms235286.aspx
Http://blog.sina.com.cn/s/blog_6f6769b50100uhzz.html
Http://openwares.net/misc/windows_x64_function_call_convention.html
The first four parameters are put into the register, instead of being pushed into the stack. Like no parameters, there is no rollback.
(Parameters are usually transmitted in registers RCX, RDX, R8, and R9 .)
For example
Void _ stdcall TestCall (int & a, int & B) { Return; } Int a = 1; Int B = 2; TestCall (a, B ); TestCall (a, B ); 201700013f031247 mov edx, dword ptr [B] 201700013f03124b mov ecx, dword ptr [a] 201700013f03124f call TestCall (13F031028h) Void _ stdcall TestCall (int & a, int & B) {Return; } 201700013f0311b0 mov dword ptr [rsp + 10 h], edx 201700013f0311b4 mov dword ptr [rsp + 8], ecx 201700013f0311b8 push rdi 201700013f0311b9 pop rdi 201700013f0311ba ret |
The Gcc compilation process is different. We will not introduce it in detail here:
Reference http://blog.sina.com.cn/s/blog_6f6769b50100uhzz.html
"Win_hate": the general rule is: when there are 6 or less parameters, the parameters are left to right in the registers: rdi, rsi, rdx, rcx, r8, r9. When there are more than 6 parameters, the first 6 are the same as the previous one, but the latter are sequentially placed from the left to the stack.
L other instructions
Refer to the instructions for these two types of calls:
Http://www.cnblogs.com/coderzh/archive/2008/12/01/1345053.html
1. _ stdcall is the default calling method of the Pascal program. It is usually used in Win32 Api. The function uses the stack pressure method from right to left and clears the stack when it exits. After compiling a function, VC adds an underline prefix to the function name, and adds "@" and the number of bytes of the parameter to the function name. Int f (void * p) --> _ f @ 4 (this function can be referenced in an external assembly language) 2. C call conventions (The C default calling convention is described by The _ cdecl keyword). pressure parameters are pushed to The stack from right to left, and The caller pushes The parameters to The stack. The memory stack of the transfer parameter is maintained by the caller (because of this, the variable parameter vararg function (such as printf) can only use this call Convention ). In addition, the function name modification conventions are also different. _ Cdecl is the default call Method for C and C ++ programs. Every function that calls it contains the code to clear the stack. Therefore, the size of the executable file generated is larger than that of the call to the _ stdcall function. The function uses the stack pressure mode from right to left. After compiling a function, VC adds an underline prefix to the function name. |
(Owed by: spring night rain http://blog.csdn.net/chunyexiyu reprint please indicate the source)