calling conventions

S

sulekhasweety

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"
 
S

santosh

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>
 
W

Walter Roberson

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 definition is fairly much correct. The more detailed explanation
in terms of ANSI/ISO C is that ANSI/ISO C does not place any restrictions
on how the implementation handles these things: how any one system
does it (in any particular compilation mode) is implementation dependant.

Correct conformant programs written entirely in C do not need to know
the implementation details. Programs that are written in a mix of
languages may need to know the details in order to ensure that the
several languages are all handling the implementation the same way
(but getting multiple languages to talk to each other is beyond the
scope of C.) And of course, the process of debugging -incorrect- programs
may require knowledge of the details in order to be able to relate
specific manifestations of undefined behaviour back to the (incorrect)
code that is triggering that behaviour.
 
R

Richard Tobin

santosh said:
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
 
F

Flash Gordon

santosh wrote, On 04/06/08 17:35:
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.

Those links have plenty of information about other than what I would
consider to be cdecl.
 
J

jacob navia

santosh said:
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.
 
K

Kenneth Brody

jacob said:
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:[email protected]>
 
S

santosh

jacob said:
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.
 
R

Richard Tobin

Kenneth Brody said:
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
 
J

jacob navia

Kenneth said:
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).
 
C

christian.bau

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top