__stdcall
This is a Microsoft-specific calling convention used by Win32 API functions. In this convention:
- Arguments are pushed from Right to Left.
- Callee cleans the stack.
main()::result = stdcallAdd(3, 4);
Ruby
line 45 : push 4 push 3 call ?stdcallAdd @@YGHHH @Z ; stdcallAdd mov DWORD PTR _result$[ebp], eax |
Like cdeclAdd(), we see that arguments are passed from Right to Left.
In line 42 in the assembly Code, we see that arguments are passed from Right to Left for function call: stdcallAdd(3, 4)
The function with calling convention __stdcall is stdcallAdd() which is called on line 42 in the main function. If we look at the assembly code of main(), after the function call, there is no statement for the stack pointer. It ends with the function call.
stdcallAdd()
Ruby
?stdcallAdd @@YGHHH @Z PROC ; stdcallAdd, COMDAT ; File c:\users\ruchit\documents\code\visual studio\visual studio\source.cpp ; Line 13 push ebp mov ebp, esp sub esp, 204 ; 000000ccH push ebx push esi push edi lea edi, DWORD PTR [ebp- 204 ] mov ecx, 51 ; 00000033H mov eax, - 858993460 ; ccccccccH rep stosd mov ecx, OFFSET __F81044A6_source @cpp call @__CheckForDebuggerJustMyCode @4 ; Line 14 mov eax, DWORD PTR _a$[ebp] add eax, DWORD PTR _b$[ebp] mov DWORD PTR _c$[ebp], eax ; Line 15 mov eax, DWORD PTR _c$[ebp] ; Line 16 pop edi pop esi pop ebx add esp, 204 ; 000000ccH cmp ebp, esp call __RTC_CheckEsp mov esp, ebp pop ebp ret 8 ?stdcallAdd @@YGHHH @Z ENDP ; stdcallAdd |
Explanation: When we look into the assembly code of stdcallAdd(), the last statement is: ret 8. This means that it increments the stack pointer by 8 bytes and pops the 2 variables that were passed to it. Then, the control returns to the main().
So, this means that callee (i.e. stdcallAdd) will clear the stack and not the caller (i.e. main).
Calling Conventions in C/C++
In C/C++ programming, a calling convention is a set of rules that specify how a function will be called. You might have seen keywords like __cdecl or __stdcall when you get linking errors. For example:
error LNK2019: unresolved external symbol "void __cdecl A(void)" (?A@@YAXXZ) referenced in function _main
Here, we see __cdecl being used. It is one of the calling conventions in C/C++. You can also see code like this in 3rd party libraries.
For example:
extern __m128i __cdecl _mm256_mask_cvtepi32_epi16(__m128i, __mmask8, __m256i);
What are caller and callee?
When we call a function, a stack frame is allocated for that function, arguments are passed to the function, and after the function does its work, the allocated stack frame is deallocated and control is passed to the calling function.
The function that calls the subroutine is called the caller. The function that gets called(i.e. subroutine) by the caller is called the callee.
C++
// C++ Program to illustrate the caller and callee #include <iostream> // callee void func() { std::cout << "Geeks" ; } // caller int main() { // function call func(); return 0; } |
Geeks
In the above code, main() is the caller and func() is the callee.
Contact Us