Figure 1     Calling Conventions

Calling Convention Argument Passing Stack Maintenance Name Decoration (C only) Notes
__cdecl Right to left. Calling function pops arguments from the stack. Underscore prefixed to function names. Ex: _Foo.  
__stdcall Right to left. Called function pops its own arguments from the stack. Underscore prefixed to function name, @ appended followed by the number of decimal bytes in the argument list. Ex: _Foo@10.  
__fastcall First two DWORD arguments are passed in ECX and EDX, the rest are passed right to left. Called function pops its own arguments from the stack. A @ is prefixed to the name, @ appended followed by the number of decimal bytes in the argument list. Ex: @Foo@10. Only applies to Intel CPUs. This is the default calling convention for Borland compilers.
thiscall this pointer put in ECX, arguments passed right to left. Calling function pops arguments from the stack. None. Used automatically by C++ code.
naked Right to left. Calling function pops arguments from the stack. None. Only used by VxDs.


Figure 2    Calling Convention Declarations


 1:    /*----------------------------------------------------------------------
 2:    MSJ Bugslayer - June '98 - John Robbins
 3:    ------------------------------------------------------------------------
 4:
 5:    This sample demonstrates how the different calling convention
 6:    declarations are set up.
 7:
 8:    ----------------------------------------------------------------------*/
 9:
 10:   // The strings passed to each function.
 11:   static char * g_szStdCall   = "__stdcall"   ;
 12:   static char * g_szCdeclCall = "__cdecl"     ;
 13:   static char * g_szFastCall  = "__fastcall"  ;
 14:   static char * g_szNakedCall = "__naked"     ;
 15:
 16:   // The extern "C" turns off all C++ name decoration.
 17:   extern "C"
 18:   {
 19:
 20:   // The __cdecl function.
 21:   void CDeclFunction ( char *        szString ,
 22:                        unsigned long ulLong   ,
 23:                        char          chChar    ) ;
 24:
 25:   // The __stdcall function.
 26:   void __stdcall StdCallFunction ( char *        szString ,
 27:                                    unsigned long ulLong   ,
 28:                                    char          chChar    ) ;
 29:   // The __fastcall function.
 30:   void __fastcall FastCallFunction ( char *        szString ,
 31:                                      unsigned long ulLong   ,
 32:                                      char          chChar    ) ;
 33:
 34:   // The naked function.  The declspec goes on the definition, not the
 35:   //  declaration.
 36:   int NakedCallFunction ( char *        szString  ,
 37:                           unsigned long ulLong    ,
 38:                           char          chChar     ) ;
 39:   }
 40:
 41:   void main ( void )
 42:   {
 00401000 55                   push        ebp
 00401001 8B EC                mov         ebp,esp
 00401003 53                   push        ebx
 00401004 56                   push        esi
 00401005 57                   push        edi
 43:       // Call each function to generate the code.  I separate each of them
 44:       //  with a couple of NOP bytes to make it easier to read the
 45:       //  disassembly.
 46:       __asm NOP __asm NOP
 00401006 90                   nop
 00401007 90                   nop
 47:       CDeclFunction ( g_szCdeclCall , 1 , 'a' ) ;
 00401008 6A 61                push        61h
 0040100A 6A 01                push        1
 0040100C A1 14 30 40 00       mov         eax,[00403014]
 00401011 50                   push        eax
 00401012 E8 45 00 00 00       call        0040105C
 00401017 83 C4 0C             add         esp,0Ch
 48:       __asm NOP __asm NOP
 0040101A 90                   nop
 0040101B 90                   nop
 49:       StdCallFunction ( g_szStdCall , 2 , 'b' ) ;
 0040101C 6A 62                push        62h
 0040101E 6A 02                push        2
 00401020 8B 0D 10 30 40 00    mov         ecx,dword ptr ds:[00403010h]
 00401026 51                   push        ecx
 00401027 E8 3D 00 00 00       call        00401069
 50:       __asm NOP __asm NOP
 0040102C 90                   nop
 0040102D 90                   nop
 51:       FastCallFunction ( g_szFastCall , 3 , 'c' ) ;
 0040102E 6A 63                push        63h
 00401030 BA 03 00 00 00       mov         edx,3
 00401035 8B 0D 18 30 40 00    mov         ecx,dword ptr ds:[00403018h]
 0040103B E8 38 00 00 00       call        00401078
 52:       __asm NOP __asm NOP
 00401040 90                   nop
 00401041 90                   nop
 53:       NakedCallFunction ( g_szNakedCall , 4 , 'd' ) ;
 00401042 6A 64                push        64h
 00401044 6A 04                push        4
 00401046 8B 15 1C 30 40 00    mov         edx,dword ptr ds:[0040301Ch]
 0040104C 52                   push        edx
 0040104D E8 40 00 00 00       call        00401092
 00401052 83 C4 0C             add         esp,0Ch
 54:       __asm NOP __asm NOP
 00401055 90                   nop
 00401056 90                   nop
 55:
 56:   }
 00401057 5F                   pop         edi
 00401058 5E                   pop         esi
 00401059 5B                   pop         ebx
 0040105A 5D                   pop         ebp
 0040105B C3                   ret
 57:
 58:   void CDeclFunction ( char *        szString ,
 59:                        unsigned long ulLong   ,
 60:                        char          chChar    )
 61:   {
 0040105C 55                   push        ebp
 0040105D 8B EC                mov         ebp,esp
 0040105F 53                   push        ebx
 00401060 56                   push        esi
 00401061 57                   push        edi
 62:       __asm NOP __asm NOP
 00401062 90                   nop
 00401063 90                   nop
 63:   }
 00401064 5F                   pop         edi
 00401065 5E                   pop         esi
 00401066 5B                   pop         ebx
 00401067 5D                   pop         ebp
 00401068 C3                   ret
 64:
 65:   void __stdcall StdCallFunction ( char *        szString ,
 66:                                    unsigned long ulLong   ,
 67:                                    char          chChar    )
 68:   {
 00401069 55                   push        ebp
 0040106A 8B EC                mov         ebp,esp
 0040106C 53                   push        ebx
 0040106D 56                   push        esi
 0040106E 57                   push        edi
 69:       __asm NOP __asm NOP
 0040106F 90                   nop
 00401070 90                   nop
 70:   }
 00401071 5F                   pop         edi
 00401072 5E                   pop         esi
 00401073 5B                   pop         ebx
 00401074 5D                   pop         ebp
 00401075 C2 0C 00             ret         0Ch
 71:
 72:   void __fastcall FastCallFunction ( char *        szString ,
 73:                                      unsigned long ulLong   ,
 74:                                      char          chChar    )
 75:   {
 00401078 55                   push        ebp
 00401079 8B EC                mov         ebp,esp
 0040107B 83 EC 08             sub         esp,8
 0040107E 53                   push        ebx
 0040107F 56                   push        esi
 00401080 57                   push        edi
 00401081 89 55 F8             mov         dword ptr [ebp-8],edx
 00401084 89 4D FC             mov         dword ptr [ebp-4],ecx
 76:       __asm NOP __asm NOP
 00401087 90                   nop
 00401088 90                   nop
 77:   }
 00401089 5F                   pop         edi
 0040108A 5E                   pop         esi
 0040108B 5B                   pop         ebx
 0040108C 8B E5                mov         esp,ebp
 0040108E 5D                   pop         ebp
 0040108F C2 04 00             ret         4
 78:
 79:   __declspec(naked) int NakedCallFunction ( char *        szString  ,
 80:                                             unsigned long ulLong    ,
 81:                                             char          chChar     )
 82:   {
 00401092 90                   nop
 00401093 90                   nop
 83:       __asm NOP __asm NOP
 84:       // Naked functions must EXPLICITLY do a return.
 85:       __asm RET
 00401094 C3                   ret

Figure 4   Parameters to Create Process

Value Type Parameter
0x0012EAB4 LPCTSTR lpApplicationName
0x0012ED20 LPTSTR lpCommandLine
0x00000000 LPSECURITY_ATTRIBUTES lpProcessAttributes
0x00000000 LPSECURITY_ATTRIBUTES lpThreadAttributes
0x00000001 BOOL bInheritHandles
0x08000000 DWORD dwCreationFlags
0x00000000 LPVOID lpEnvironment
0x00000000 LPCTSTR lpCurrentDirectory
0x0012EA2C LPSTARTUPINFO lpStartupInfo
0x0012ECC8 LPPROCESS_INFORMATION lpProcessInformation