This can be done as follows:
mov esi, esp push arg3 push arg2 push arg1 call [SomeExternalProc] mov esp, esi ; now the stack is always properly cleaned
An external procedure must save esi. Or you can use any other register stored by an external procedure, or even a memory variable - local or global.
Well, the order of the arguments is the same for CDECL and STDCALL - in reverse order.
source share