In Assembly Language, Seventh Edition for x86 Processors by Kip Irvine, on page 325, it says under 8.2.4 32-Bit Calling Conventions,
The C Calling Convention ... The C calling convention solves the problem of cleaning up the runtime stack in a simple way: When a program calls a subroutine, it follows the
CALL
instruction with a statement that adds a value to the stack pointer (ESP
) equal to the combined sizes of the subroutine parameters. Here is an example in which two arguments (5 and 6) are pushed on the stack before executing aCALL
instruction,Example1 PROC push 6 push 5 call AddTwo add esp, 8 ret Example1 ENDP
Therefore programs written in C/C++ always remove arguments from the stack in the calling program after a subroutine has returned.
It goes on to say
STDCALL Calling Convention Another common way to remove parameters from the stack is to use the convention named
STDCALL
. In the followingAddTwo
procedure, we supply an interger parameter to theRET
instruction, which in turn adds 8 to ESP after returning to the calling procedure. The integer must equal the number of bytes of stack space consumed by the procedure's parameters:AddTwo PROC push ebp mov ebp,esp mov eax,[ebp+12] add eax,[ebp+8] pop ebp ret 8 AddTwo ENDP
It should be pointed out that
STDCALL
, like C, pushes arguments onto the stack in reverse order. By having a prameter in theRET
instruction,STDCALL
reduces the amount of code generated for subroutine calls (by one instruction) and ensures that calling programs will never forget to clean up the stack. The C calling convention on the other hand, permits subroutines to declare a variable number of parameters. The caller can decide how many arguments it will pass.