Now at some point when writing C or C++ code you've come across
those funny things in front of functions..e.g. __stdcall or possibly __cdecl.
Have you ever wondered what they are for? Well its all to do with the
calling convention of a function. The windows API uses the __stdcall for
its Win32 API's. Hopefully this mini Tutorial will clear some points that
you may have... and show you the inner workings of function calls. I used
Visual C++ to compile most of my demo's, but most if not all C/C++ compilers
should follow this calling convention.

Which are Calling
Conventions

A Calling Convention is a definition like a function....how
parameters are passed and returned ...this is mostly accomplished using the
stack. But then comes the details of the order of passing the variables on
the stack, and who is responsible for tidying the stack up afterwards. In
a program the Calling Conventions is not usually so important - but for
communication over program borders (e.g. to the re-entry point in DLL) however a
generally accepted definition is necessary!
Under Windows there are fundamentally three Calling convention ( __cdecl, __stdcall
and __fastcall) and are exaplaned below in the following table:

__ cdecl

(C calling convention)

Function names are
'decorated' with a prefixed underscore character '_'

Parameter from right to the
left are placed on the stack.

Stack cleanup is performed by the

caller. (not the function)

(This is the default calling
convention for C/C++ programs)

When calling a function, inside the function, the registers ESI, EDI,
EBX and EBP are saved on the stack - and is usually generated by the
compiler. So in most cases you'll find a prolog and a epilog that
saves and restores these registers.

An Example Function:

// __cdecl example function

int__cdecl sum(int
a, int b)

{

return a+b;

}

Calling the function:

// Calling it in C looks like this:

int r =
sum(1, 2);

// Calling it in assembly

; push
arguments onto the stack from right to left

push 2

push 1

; call our
function

call _sum

; cleanup the
stack by adding the size of the arguments to the ESP registerr

; (where ESP
is the 32 bit stack pointer registerr)

add
esp, 8

; save our
returned value into a memory location

mov
dword ptr[r], eax

Function in Assembly:

// Assembly code for the function example function would look like
this:

; function
prolog.

push
ebp ; Function pro log

mov ebp,
esp ; Function pro log (Stackframe)

; return
a+b

mov
eax, dword ptr[a]

add
eax, dword ptr[b]

; function
epilog.

pop
ebp ; Restore old
Stackframe

ret

__ stdcall

(Standard calling convention)

Parameter from right to the
left on the stack - function clears up the stack

Stack cleanup is performed by the called function.

The Function name is 'decorated' by a prepending an underscore
character at the front of the funciton name, and appending a '@'
character to the end..WITH the number of bytes of stack space required.

Since windows API's use the __stdcall convention, if you look deep
inside the header files you'll find this:

#define
WINAPI __stdcall

As so often programmers get used to using WINAPI for function
prototypes....but forget what it actually is.

An Example
Function:

// __stdcall example function

int__stdcall sum(int
a, int b)

{

return a+b;

}

Calling our function:

// Calling it in C looks like this:

int r =
sum(1, 2);

// Calling it in assembly

; push
arguments onto the stack from right to left

push 2

push 1

; call our
function

call _sum@8

; save our
returned value into a memory location

mov
dword ptr[r], eax

Representing our function in Assembly:

// Assembly code for the function example function would look like
this:

; function
prolog.

( Same as
__cdecl)

; return
a+b

mov
eax, dword ptr[a]

add
eax, dword ptr[b]

; function
epilog.

( Same as
__cdecl)

; cleanup the
stack

add
esp, 8

; On some assemblers, you might see

; ret 8

; Which restores the stack then returns :)

; return
from our function

ret

An interesting thing to notice with __stdcall, is that we can't pass
a variable number of arguments to the function, as you can with __cdecl...
an example of where you do this is with printf(..). This is
because the function is doing the cleanup, and doesn't know how many
variables your passing, but with __cdecl, the caller does the cleanup so
it knows how many variables where pushed on the stack.

__fastcall

(Fast calling convention)

First two
parameters passed to the function are passed using registers ECX and EDX.
The rest of them are pushed on the stack from right to left.

The
function is responsible for cleaning up the stack.

Function name is 'decorated' by prepending a '@' character at the
front of the function name, and appending a '@' on the end,... WITH the
number of bytes (decimal) of space required byt the arguments.

An
Example Function:

// __fastcall example function

int__fastcall sum(int
a, int b)

{

return a+b;

}

Calling our function:

// Calling it in C looks like this:

int r =
sum(4, 3);

// Calling it in assembly

; push
arguments onto the stack from right to left

mov
ebx, 4

mov
ecx, 2

; call our
function

call @sum@8

; save our
returned value into a memory location

mov
dword ptr[r], eax

Representing the function in Assembly:

_a$ = -4
_b$ = -8

// Function code in Assembly Language

; function
prolog.

push
ebp ; Function pro log

mov ebp,
esp ; Function pro log (Stackframe)

pop
ecx

mov DWORD
PTR _b$[ebp], ebx

mov DWORD
PTR _a$[ebp], ecx

; return
a+b

mov
eax, DWORD PTR _a$[ebp]

add

eax, DWORD PTR _b$[ebp]

; function
epilog.

mov
esp, ebp ; Restore old stack

pop
ebp ; Restore old
Stackframe

ret
0

So is __fastcall any faster? Well in certain situations yes...
but your free to test it out yourself.

Thiscall

Arguments are passed from right to left on the stack.
The this pointer is placed in ECX.

Stack cleanup is performed by the calling function.

Its the default calling convention for C++ compilers.

[ Now if a variable number of arguments have to be passed - in that
case __cdecl would be used, and
this pointer would be pushed on the stack
last. ]

__ pascal

Parameter from left to the
right on the stack - function clears up the stack

__ nearly
call

First the parameters in
registers are assigned - then the stack is used.

Return values:

8 bits of
values

in
the register AL

16 bits of values

in the register
AX
,

32 bits
of values

in
the register EAX

Visitor: 9534626 &nbsp{ 209.237.238.175 }

Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.