By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,214 Members | 2,066 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,214 IT Pros & Developers. It's quick & easy.

calling conventions

P: n/a
Hi,

the following is the definition for calling convention ,which I have
seen in a text book, can anyone give a more detailed explanation in
terms of ANSI - C

"the requirements that a programming system places on how a procedure
is called and how data is passed between a calling program and
procedures are called calling conventions"
Jun 27 '08 #1
Share this Question
Share on Google+
10 Replies


P: n/a
su***********@gmail.com wrote:
Hi,

the following is the definition for calling convention ,which I have
seen in a text book, can anyone give a more detailed explanation in
terms of ANSI - C

"the requirements that a programming system places on how a procedure
is called and how data is passed between a calling program and
procedures are called calling conventions"
The C language leaves it up to each implementation to use whatever
calling conventions that suit them best. Almost always a C compiler
will default to the calling convention that the targeted host employs.
The most common calling convention is the so-called "C calling
convention" or "cdecl" used on the majority of C implementations.
Programs written to use the Windows API use Microsoft's "stdcall"
convention. Many other conventions like "fastcall" are possible.
Generally you should leave it to the compiler to chose the calling
convention.

<http://www.openwatcom.org/index.php/Calling_Conventions>
<http://en.wikipedia.org/wiki/Calling_convention>

Jun 27 '08 #2

P: n/a
In article <g2**********@registered.motzarella.org>,
santosh <sa*********@gmail.comwrote:
>Programs written to use the Windows API use Microsoft's "stdcall"
convention.
That's probably almost always true, but it's more directly because
they are using the Windows ABI, not API.

-- Richard
--
In the selection of the two characters immediately succeeding the numeral 9,
consideration shall be given to their replacement by the graphics 10 and 11 to
facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)
Jun 27 '08 #3

P: n/a
santosh wrote, On 04/06/08 17:35:
su***********@gmail.com wrote:
>Hi,

the following is the definition for calling convention ,which I have
seen in a text book, can anyone give a more detailed explanation in
terms of ANSI - C

"the requirements that a programming system places on how a procedure
is called and how data is passed between a calling program and
procedures are called calling conventions"

The C language leaves it up to each implementation to use whatever
calling conventions that suit them best. Almost always a C compiler
will default to the calling convention that the targeted host employs.
The most common calling convention is the so-called "C calling
convention" or "cdecl" used on the majority of C implementations.
I would not be so sure of that were I use. "cdecl" as I've heard the
term used has all parameters passed on the stack but on several
architectures it is normal to pass some parameters in registers (even
before you get to optimisations). I think the tendency is moving even
more towards parameters being passed in registers (MS have gone this ay
on their 64 bit ABI).
Programs written to use the Windows API use Microsoft's "stdcall"
convention.
Now, would that be 16, 32 and 64 bit Windows on X86/X64 and all the
various mobile versions of Windows?
Many other conventions like "fastcall" are possible.
Generally you should leave it to the compiler to chose the calling
convention.
Yes, leaving it as default for the implementation is almost always the
right thing to do and further more ignoring it is normally the right
thing to do.
<http://www.openwatcom.org/index.php/Calling_Conventions>
<http://en.wikipedia.org/wiki/Calling_convention>
Those links have plenty of information about other than what I would
consider to be cdecl.
--
Flash Gordon
Jun 27 '08 #4

P: n/a
santosh wrote:
Programs written to use the Windows API use Microsoft's "stdcall"
convention.
That was true under 32 bit windows. 64 bit windows uses "fastcall"
everywhere. It is a convention where 4 registers hold the
first 4 parameters of the function. With 64 bit wide registers
you can pass a long long in a register now.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jun 27 '08 #5

P: n/a
jacob navia wrote:
>
santosh wrote:
Programs written to use the Windows API use Microsoft's "stdcall"
convention.

That was true under 32 bit windows. 64 bit windows uses "fastcall"
everywhere. It is a convention where 4 registers hold the
first 4 parameters of the function. With 64 bit wide registers
you can pass a long long in a register now.
Just curious...

How does one take the address of one of the first 4 parameters? (I
suppose the compiler would have to do something such as store it on
the stack temporarily and then take that address?)

Note that I have seen implementations (long ago, I forget which
platform) which did exactly as you state -- the first N parameters to
non-varadic functions were passed in registers. (Yet another case of
"no prototype in scope for varadic function == UB".)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Jun 27 '08 #6

P: n/a
jacob navia wrote:
santosh wrote:
>Programs written to use the Windows API use Microsoft's "stdcall"
convention.

That was true under 32 bit windows. 64 bit windows uses "fastcall"
everywhere. It is a convention where 4 registers hold the
first 4 parameters of the function. With 64 bit wide registers
you can pass a long long in a register now.
Thanks to both Flash Gordon and jacob navia for the corrections. I admit
unfamiliarity with 64 bit Windows.

Jun 27 '08 #7

P: n/a
In article <48***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
>How does one take the address of one of the first 4 parameters? (I
suppose the compiler would have to do something such as store it on
the stack temporarily and then take that address?)
Yes. As far as C is concerned, there are some expressions in the
calling function, and their values get assigned to some variables
in the called function. The procedure call protocol is just a way
of making that happen; it can be as simple or as complicated as
necessary. For another example, consider passing structs: this
may involve passing an address on the stack or in a register, with
a copy of the struct contents in the called function.
>Note that I have seen implementations (long ago, I forget which
platform) which did exactly as you state -- the first N parameters to
non-varadic functions were passed in registers.
This is common on architectures with a reasonable number of registers,
which more or less means everything except x86. Sparc and PPC are
examples.

-- Richard
--
In the selection of the two characters immediately succeeding the numeral 9,
consideration shall be given to their replacement by the graphics 10 and 11 to
facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)
Jun 27 '08 #8

P: n/a
Kenneth Brody wrote:
jacob navia wrote:
>santosh wrote:
>>Programs written to use the Windows API use Microsoft's "stdcall"
convention.
That was true under 32 bit windows. 64 bit windows uses "fastcall"
everywhere. It is a convention where 4 registers hold the
first 4 parameters of the function. With 64 bit wide registers
you can pass a long long in a register now.

Just curious...

How does one take the address of one of the first 4 parameters? (I
suppose the compiler would have to do something such as store it on
the stack temporarily and then take that address?)
If you're careful to distinguish between "parameter" and
"argument" the answer should be clear. An "argument" is a
value provided by the caller, and a "parameter" or "formal
parameter" is a function-local variable initialized from an
argument value. If a calling convention requires the first N
argument values to be passed in registers, that doesn't mean
the first N parameters need to reside in registers throughout
their lifetimes. (Turn it around: If the argument values arrive
on a stack, does that mean the optimizer can't put the parameters
in registers?)
Note that I have seen implementations (long ago, I forget which
platform) which did exactly as you state -- the first N parameters to
non-varadic functions were passed in registers. (Yet another case of
"no prototype in scope for varadic function == UB".)
SPARC has done this since it was first designed. The
first N argument values are passed in registers, even for
variadic functions. (Consequence: The <stdarg.hmachinery
is more involved than for memory-only calling conventions.)

Alpha uses registers to carry at least some arguments;
it's been a long time since I worked with Alpha machines and
I've forgotten the details.

It's my informal impression that most CPU designs less
than about two decades old pass at least some argument values
in registers; registers nowadays are a few decimal orders of
magnitude faster than memory (although that's not an entirely
fair comparison, what with store buffers and caches and all).
The CPUs that rely heavily on memory-resident arguments seem
to be those that have backward-compatibility issues with older
designs.

By the way, sometimes the "argument" value passed by the
calling convention isn't exactly the same as the "argument"
as seen in the C source. For example, some calling conventions
pass struct- and union-valued arguments by putting them in
unnamed memory-resident temporaries and passing pointers instead.
Some functions that return struct or union values are implemented
as if they were void functions with an extra, hidden argument
that points to a result location. What you see in the C may be
a little different than what you see in the debugger.

--
Er*********@sun.com
Jun 27 '08 #9

P: n/a
Kenneth Brody wrote:
jacob navia wrote:
>santosh wrote:
>>Programs written to use the Windows API use Microsoft's "stdcall"
convention.
That was true under 32 bit windows. 64 bit windows uses "fastcall"
everywhere. It is a convention where 4 registers hold the
first 4 parameters of the function. With 64 bit wide registers
you can pass a long long in a register now.

Just curious...

How does one take the address of one of the first 4 parameters? (I
suppose the compiler would have to do something such as store it on
the stack temporarily and then take that address?)
Exactly.

Before calling a function you should subtract 32 bytes from the stack
pointer. The called procedure can (if it wants) store in that space
the values it received in the registers. Lcc-win64 does that in
a debug setting so that the debugger can figure out where the values
of the parameters are...
Note that I have seen implementations (long ago, I forget which
platform) which did exactly as you state -- the first N parameters to
non-varadic functions were passed in registers. (Yet another case of
"no prototype in scope for varadic function == UB".)
Variadic functions are QUITE difficult in this setting, and I
had a LOT of bugs in the code generation. Basically, I store all
the registers that could possibly carry an argument (rcx, rdx,
r8,r9,xmm0,xmm1,xmm2,xmm3) into a continuous stack area and
maintain a pointer to the integer or pointer part, and another
pointer to the floating point part. Up to 4 floating point values
could be passed in xmm0-xmm3. Since the procedure doesn't know
at the start what values are being passed to it, it must save
all of them and va_arg() will pull the corresponding value
from either

o the integer or pointer stack, or
o from the floating point stack
o or from the actual stack where values are passed like
structures or long doubles.

This is relatively easy. MUCH more complex are the linux 64 conventions
(a nightmare).
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jun 27 '08 #10

P: n/a
On Jun 4, 9:34 pm, Kenneth Brody <kenbr...@spamcop.netwrote:
Note that I have seen implementations (long ago, I forget which
platform) which did exactly as you state -- the first N parameters to
non-varadic functions were passed in registers. (Yet another case of
"no prototype in scope for varadic function == UB".)
PowerPC did that. The compiler assumed that the first eight vararg
parameters were passed in registers, and that the caller had reserved
enough space in memory so that the called function could save these
eight registers (va_list works much easier if everything is in
memory). When a vararg function was called without prototype, the
caller wouldn't reserve the space, so the called function would
clobber 32 bytes somewhere.
Jun 27 '08 #11

This discussion thread is closed

Replies have been disabled for this discussion.