f



"C" calling convention on x86

Good day,

in attempting to call externally compiled "C" code from asm, I've been 
trying to understand the "C" calling convention on x86. Below is what I 
think to be the way it all works.

If anybody could confirm/deny/correct this I'd be most grateful.

The 'C' calling convention on a x86:
====================================

- args are pushed right to left

- caller must free args

Arguments:
----------

- 1, 2 or 4 byte integers pushed onto stack as single DWORDs

- 8 byte integers are pushed onto stack as two DWORDs, the most
    significant DWORD is pushed first

- 4 byte floating point no's pushed onto stack as single DWORDs

- 8 byte floating point no's are stored in two DWORDs on stack,
    typically transferred from top of FP register stack as
    'fstp QWORD PTR [esp]'

- composite 'structs' are passed on the stack, stored in the
    minimum number of DWORDs large enough to hold them

Returns:
--------

- 1, 2, 4 byte integers are returned in EAX

- 8 byte integers are returned in EAX and EDX,
    the most significant DWORD is in EDX

- both 4 and 8 byte floating point no returns are returned on top of
    FP register stack (so are at extended precision)

- caller must allocate stack space for returned composite 'structs',
    address of this space is passed to callee as final (and extra)
    DWORD on stack, callee returns address of returned struct in EAX


Thanks

Mike

0
Mike
8/11/2004 5:25:34 PM
comp.lang.asm.x86 5035 articles. 0 followers. Post Follow

27 Replies
867 Views

Similar Articles

[PageSpeed] 54

> - 4 byte floating point no's pushed onto stack as single DWORDs
>
Except when dealing with variable-argument functions, here 4-byte
floating point values (real4, float, whatever) will be promoted to
8-byte double (I believe this is standardized C behaviour, too lazy
to look it up in the reference though.)

Whether floating-point numbers are returned on FP stack or registers,
and whether 8byte integers are supported (and how they are returned)
depends on the compiler. I think some old(er) 32bit compiler used to
return floats in EAX or EDX:EAX, where other use the fp stack...


0
f0dder
8/11/2004 6:48:56 PM
Mike wrote:
> Good day,
> 
> in attempting to call externally compiled "C" code from asm, I've been 
> trying to understand the "C" calling convention on x86. Below is what I 
> think to be the way it all works.

It depends on the operating system you are using, the compiler you are
using, and even what mode you are using to call the function in. For example,
Windows has its own calling convention, that does not match anyone elses,
and they have two different calling conventions depending on if you are
calling the operating system, or simply another function in the same
program.

-- 
Samiam is Scott A. Moore

Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas

Being right is more powerfull than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.

0
Scott
8/11/2004 7:11:04 PM
Scott Moore <spamtrap@crayne.org> wrote:
> Mike wrote:
>> Good day,
>> 
>> in attempting to call externally compiled "C" code from asm, I've been 
>> trying to understand the "C" calling convention on x86. Below is what I 
>> think to be the way it all works.

> It depends on the operating system you are using, the compiler you are
> using, and even what mode you are using to call the function in. For example,
> Windows has its own calling convention, that does not match anyone elses,
> and they have two different calling conventions depending on if you are
> calling the operating system, or simply another function in the same
> program.

> -- 
> Samiam is Scott A. Moore

The poster was asking about the "C" calling convention. That
convention does not depend on what compiler or mode. Windows API
functions do not use this convention. They use the STDCALL convention
which is almost identical to the C calling convention. The big
difference is that the called function is responsible for removing
parameters from the stack (similar to the PASCAL convention).

The only thing I can think that varies for the C convention is the
mangling of names. This can vary based on the object file format.
Most Windows compiler add a underscore to the front of funciton names
(e.g., _main is the label for the main() function). However, Linux
ELF object files do not mangle the name at all.

See my web site for lots of example code:
http://www.drpaulcarter.com/pcasm/

--
Paul Carter

0
spamtrap
8/11/2004 10:33:04 PM
yeah I *believe* the name mangling is optional... I've never seen dos/windows
compilers that didn't prefix the underscore but it is not uncommon for example for
embedded compilers to omit it.  I think some compilers may even give you the option
as a command line parameter as to whether to add a prefix, and some may even let
you specify the prefix.

David


0
David
8/12/2004 2:14:56 AM
spamtrap@crayne.org wrote:
> Scott Moore <spamtrap@crayne.org> wrote:
> 
>>Mike wrote:
>>
>>>Good day,
>>>
>>>in attempting to call externally compiled "C" code from asm, I've been 
>>>trying to understand the "C" calling convention on x86. Below is what I 
>>>think to be the way it all works.
> 
> 
>>It depends on the operating system you are using, the compiler you are
>>using, and even what mode you are using to call the function in. For example,
>>Windows has its own calling convention, that does not match anyone elses,
>>and they have two different calling conventions depending on if you are
>>calling the operating system, or simply another function in the same
>>program.
> 
> 
>>-- 
>>Samiam is Scott A. Moore
> 
> 
> The poster was asking about the "C" calling convention. That
> convention does not depend on what compiler or mode. Windows API
> functions do not use this convention. They use the STDCALL convention
> which is almost identical to the C calling convention. The big
> difference is that the called function is responsible for removing
> parameters from the stack (similar to the PASCAL convention).
> 

The registers used to pass parameters can vary. The convention may
use the stack for parameters. It may use registers. It may use
a combination of both. The function result can be contained in a
register, or it may be on the stack. Registers may be specified
as preserved by the caller, callee, or a combination of both. There
are even compilers that pass the parameters in fixed global locations.

There is no such animal as a "universal" C calling convention.

-- 
Samiam is Scott A. Moore

Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas

Being right is more powerfull than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.

0
Scott
8/12/2004 7:49:38 AM
"Scott Moore" <spamtrap@crayne.org> wrote in message
news:05FSc.272350$JR4.143773@attbi_s54...
[...]
> The registers used to pass parameters can vary. The convention may
> use the stack for parameters. It may use registers. It may use
> a combination of both. The function result can be contained in a
> register, or it may be on the stack. Registers may be specified
> as preserved by the caller, callee, or a combination of both. There
> are even compilers that pass the parameters in fixed global locations.
>
> There is no such animal as a "universal" C calling convention.

Anyone who wans to dispute this statement should post (and subsequently get
flamed for being "off-topic") on comp.lang.c. The "C" calling convention is
just a Microsoft misnomer. AFAIK it is the same as the System V calling
convention.

-Matt

0
Matt
8/12/2004 4:26:38 PM
There isn't an "official" C calling convention, but still it is mostly
standardized.  UNIX calling convention is standardized in the UNIX
ABI.  You can find more about it at the Linux Standards Base.  I'll
assume you're working from a UNIX-based system.

> - args are pushed right to left

yes

> - caller must free args

Caller must _pop_ args.  If the arg is a pointer to heap-allocated
memory, then who frees it depends on the function itself.


> - 1, 2 or 4 byte integers pushed onto stack as single DWORDs

yep

> - 8 byte integers are pushed onto stack as two DWORDs, the most
>     significant DWORD is pushed first

unsure

> - 4 byte floating point no's pushed onto stack as single DWORDs
> 
> - 8 byte floating point no's are stored in two DWORDs on stack,
>     typically transferred from top of FP register stack as
>     'fstp QWORD PTR [esp]'

can't answer about FP.

> - composite 'structs' are passed on the stack, stored in the
>     minimum number of DWORDs large enough to hold them

You cannot pass "structs" as arguments in C, unless that changed in
C99 (C++ allows this, but it has a completely different,
unstandardized calling convention).  You can only pass pointers to
structs in C.

> Returns:
> --------
> 
> - 1, 2, 4 byte integers are returned in EAX

Yep.

> - caller must allocate stack space for returned composite 'structs',
>     address of this space is passed to callee as final (and extra)
>     DWORD on stack, callee returns address of returned struct in EAX

composite structs not passed in "C" calling convention.

Also note that the following registers need to be saved in the "C"
calling convention: %ebx, %edi, %esi.  For position-independent code,
%ebx holds the address of the global offset table.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

0
spamtrap
8/12/2004 8:07:57 PM
Scott Moore <spamtrap@crayne.org> wrote:

>> The poster was asking about the "C" calling convention. That
>> convention does not depend on what compiler or mode. Windows API
>> functions do not use this convention. They use the STDCALL convention
>> which is almost identical to the C calling convention. The big
>> difference is that the called function is responsible for removing
>> parameters from the stack (similar to the PASCAL convention).
>> 

> The registers used to pass parameters can vary. The convention may
> use the stack for parameters. It may use registers. It may use
> a combination of both. The function result can be contained in a
> register, or it may be on the stack. Registers may be specified
> as preserved by the caller, callee, or a combination of both. There
> are even compilers that pass the parameters in fixed global locations.

> There is no such animal as a "universal" C calling convention.

> -- 
> Samiam is Scott A. Moore

If functions that are declared with __cdecl follow the same convention
for Borland, MS, Watcom and gcc compilers, you don't call that universal?
(Remember the poster was taking about the x86 platform.)

-- 
Paul Carter 

0
spamtrap
8/13/2004 1:36:37 AM
Jonathan Bartlett wrote:

> You cannot pass "structs" as arguments in C, unless that changed
> in C99.  You can only pass pointers to structs in C.

??

$ cat foo.c
#include <stdio.h>

struct foo { int a, b, c, d; };

struct foo add(struct foo x, struct foo y)
{
   struct foo res;

   res.a = x.a + y.a;
   res.b = x.b + y.b;
   res.c = x.c + y.c;
   res.d = x.d + y.d;

   return res;
}

int main(void)
{
   struct foo x = { 1, 2, 3, 4 }, y = { 5, 6, 7, 8 }, z;

   z = add(x,y);

   printf("%i %i %i %i\n", z.a, z.b, z.c, z.d);

   return 0;
}

$ gcc-3.4.0 -std=c89 -pedantic -Wall -Wextra foo.c

$ ./a.out
6 8 10 12

-- 
Regards, Grumble

0
Grumble
8/13/2004 9:41:30 AM
>If functions that are declared with __cdecl follow the same convention
>for Borland, MS, Watcom and gcc compilers, you don't call that universal?
>(Remember the poster was taking about the x86 platform.)

Because until MS became dominant, there were many different conventions
used.  THe older Borland C compilers did not handle floats the way MS
did.  Lattice C and DeSmet C used somewhat different conventions.  ANd
MS 16 bit compilers used several different variants over the years, the
32 bit compilers use something quite similar to the last variant the 16
bit compilers used (with size and register availability variations).  

SO __cdecl may be rather consistent on "modern" x86/Win but 
on x86/NonWin and older x86/Win and x86/DOS you canNOT depend upon the
same behavior or interfaces.  ANd as soon as you go to implementations
of C compilers on non-x86 platforms, things get much more variable.

Finally, the original poster said NOTHING about __cdecl, but instead:
>in attempting to call externally compiled "C" code from asm,
and __cdecl is NOT part of the C standard, the double underscore at
the beginning indicates an extension, usually proprietary, and if
you try to call between asm and C using Watcom, it doesn't do anything
at all like MS does (unless, of course, you use __cdecl or one of the 
other overrides).  So, Watcom doesn't do the same as MS if you limit
yourself to standard C (which does NOT specify calling conventions,
as another poster noted: "... should post (and subsequently get
flamed for being "off-topic") on comp.lang.c").  

The interface between asm and HLLs is usually not part of the language
standard in any HLL language.  That MS has defined a defacto 
standard for x86/Win and calls it __cdecl is worth noting -- as an MS
defacto standard, and not to be depended upon in non-Win x86 venues.
Telling the OP to depend upon __cdecl is an unintentional dis-service,
because it has the high likelihood of being mis-leading. OP said
nothing about Win/x86, only x86.  Maybe he is targeting Linux, or OS9,
or QNX or even DOS -- until you know for sure ...

0
Kevin
8/13/2004 4:20:25 PM
Matt Taylor wrote:
> "Scott Moore" <spamtrap@crayne.org> wrote in message
> news:05FSc.272350$JR4.143773@attbi_s54...
> [...]
> 
>>The registers used to pass parameters can vary. The convention may
>>use the stack for parameters. It may use registers. It may use
>>a combination of both. The function result can be contained in a
>>register, or it may be on the stack. Registers may be specified
>>as preserved by the caller, callee, or a combination of both. There
>>are even compilers that pass the parameters in fixed global locations.
>>
>>There is no such animal as a "universal" C calling convention.
> 
> 
> Anyone who wans to dispute this statement should post (and subsequently get
> flamed for being "off-topic") on comp.lang.c. The "C" calling convention is
> just a Microsoft misnomer. AFAIK it is the same as the System V calling
> convention.
> 
> -Matt
> 

Fine. Please quote where in the white book on C, or in the ANSI standard on
C, does it specify the assembly language details of C calls ?

Again, no such animal. System V is only one calling convention, was produced
by AT&T, and is neither standard, nor binding on anyone.

NO high level language specifies its assembly level details. Thats why they
call it a "high level langauge".

-- 
Samiam is Scott A. Moore

Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas

Being right is more powerfull than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.

0
Scott
8/14/2004 12:01:06 AM
spamtrap@crayne.org wrote:

> Scott Moore <spamtrap@crayne.org> wrote:
> 
> 
>>>The poster was asking about the "C" calling convention. That
>>>convention does not depend on what compiler or mode. Windows API
>>>functions do not use this convention. They use the STDCALL convention
>>>which is almost identical to the C calling convention. The big
>>>difference is that the called function is responsible for removing
>>>parameters from the stack (similar to the PASCAL convention).
>>>
> 
> 
>>The registers used to pass parameters can vary. The convention may
>>use the stack for parameters. It may use registers. It may use
>>a combination of both. The function result can be contained in a
>>register, or it may be on the stack. Registers may be specified
>>as preserved by the caller, callee, or a combination of both. There
>>are even compilers that pass the parameters in fixed global locations.
> 
> 
>>There is no such animal as a "universal" C calling convention.
> 
> 
>>-- 
>>Samiam is Scott A. Moore
> 
> 
> If functions that are declared with __cdecl follow the same convention
> for Borland, MS, Watcom and gcc compilers, you don't call that universal?
> (Remember the poster was taking about the x86 platform.)
> 

Microsoft Windows uses a different convention than Linux. In any case,
Linux follows the AT&T convention, which is not, nor never was a "standard"
of any kind. It was just AT&T's statement of THEIR calling convention.

-- 
Samiam is Scott A. Moore

Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas

Being right is more powerfull than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.

0
Scott
8/14/2004 12:02:29 AM
I guess just about everyone and their dog know what is intended with
reference to a "C" calling convention, a variable number of parameters
pushed in reverse and the caller balances the stack. Now this won't
help you with "other" hardware that is not constructed like x86 where
stack assumptions don't matter but most have played at some stage with
x86 so they will know the difference.

For those who wrote Windows code back in the 16 bit days, the PASCAL
calling convention has been changed to something that looks like
STDCALL so that old 16 bit code could be more easily ported to 32 bit
windows. Stuff like,

int far pascal FunctionName( etc ...

is treated as

int __stdcall FunctionName( etc ...

and languages liker basic, pascal and fortran that used the pascal
convention appear to have been ignored.

The current "preferred" calling convention from Microsoft is COM with
its tacky multiple levels of indirection so they can port it to RISC
hardware at some stage in the future.

This is why I will stick to whittling bits of binary in x86 assembler
for some time to come. :)

Regards,

hutch art movsd dot com

0
spamtrap
8/14/2004 1:15:25 AM
hutch-- wrote:

> I guess just about everyone and their dog know what is intended with
> reference to a "C" calling convention, a variable number of parameters
> pushed in reverse and the caller balances the stack. Now this won't
> help you with "other" hardware that is not constructed like x86 where
> stack assumptions don't matter but most have played at some stage with
> x86 so they will know the difference.

There are PLENTY of x86 C compilers that DON'T use stack calling convention
only.

In fact, any modern, register based calling convention does not do this.
The stack based calling convention is VERY inefficent

-- 
Samiam is Scott A. Moore

Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas

Being right is more powerfull than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.

0
Scott
8/14/2004 1:51:56 AM
Scott Moore  <spamtrap@crayne.org> wrote:
>
>Microsoft Windows uses a different convention than Linux. In any case,
>Linux follows the AT&T convention, which is not, nor never was a "standard"
>of any kind. It was just AT&T's statement of THEIR calling convention.

gcc on Linux pushes right-to-left, caller fixes the stack.  That's
identical to the Windows standard.  What is it that you mean by "AT&T
convention"?
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Tim
8/14/2004 5:30:35 AM
Scott Moore <spamtrap@crayne.org> wrote:
> In fact, any modern, register based calling convention does not
> do this.  The stack based calling convention is VERY inefficent

I kinda think that what `c` does is a little OT here.  We don't
need to import langauge wars, we have enough of our own!  But when
you talk efficiency, you're going to the heart of ASM.

Why do you say a stack parameters is "VERY inefficient"?

The near stack will need to be in L1 cache anyways, and many of
the calls now takes too many parms or have variable # of parms.

Admittedly register parms is never(?) slower than stack but
the difference is small except perhaps very short functions.
These should be inlined anyways.

The Linux kernel uses register parms for syscalls because it
_is_ a bit easier to access registers than userspace memory
after a ring shift.  But it isn't _that_ hard -- *BSD put
syscall parms on the userspace stack.

-- Robert

0
Robert
8/14/2004 1:38:05 PM
Scott,

I have no problems with compilers performing all sorts of tricks that
vary from stack based parameter passes but for the obvious reason,
when you pass 12 parameters, forget register based conventions like
the defacto FASTCALL.

You will probably like the internals of the VCTOOLKIT optimiser which
among many other things, shifts locals from -ESP values to +ESP values
and has them as part of the argument list passed to the proc.

The whole range of theory about stack overhead falls over when it
comes to application design. If a procedure is of any reasonable size,
the stack overhead does not matter (benchmarked) and if the procedure
is small enough for it to matter, it is far faster to directly inline
the code (also benchmarked).

The virtue of the C calling convention has always been its capacity to
pass a variable number of parameters, not its efficiency.

Regards,

hutch at movsd dot com

0
spamtrap
8/15/2004 1:02:08 AM
Robert Redelmeier wrote:
> Scott Moore <spamtrap@crayne.org> wrote:
> 
>>In fact, any modern, register based calling convention does not
>>do this.  The stack based calling convention is VERY inefficent
> 
> 
> I kinda think that what `c` does is a little OT here.  We don't
> need to import langauge wars, we have enough of our own!  But when
> you talk efficiency, you're going to the heart of ASM.
> 
> Why do you say a stack parameters is "VERY inefficient"?
> 
> The near stack will need to be in L1 cache anyways, and many of
> the calls now takes too many parms or have variable # of parms.
> 
> Admittedly register parms is never(?) slower than stack but
> the difference is small except perhaps very short functions.
> These should be inlined anyways.
> 
> The Linux kernel uses register parms for syscalls because it
> _is_ a bit easier to access registers than userspace memory
> after a ring shift.  But it isn't _that_ hard -- *BSD put
> syscall parms on the userspace stack.
> 
> -- Robert
> 

Its a good question. This is not really the correct forum, since this
group is not about compilers.

However, you asked the question reasonably, so you will get my reasonable
answer.

If the goal is to pass parameters in registers, but nothing else, then
a compiler may well generate code that is a push, or even less effective
than stack based calling schemes. The reason is simple. Before each call,
the compiler is effectively scrambling to get the proper information into
place in assigned registers. At the top of the called routine, the compiler
must reverse this, getting the parameters stored elsewhere for safekeeping
before the registers they occupy are used (and destroyed).

Indeed, this is what happened when many of the low performing compilers of
the 1980's tried to use register passing conventions. This was used as
"proof" that the register based calling conventions don't "work".
The difference is that a very advanced compiler can plan both the approach
to the call, and the sequence at the top of the routine, so that the
registers used for parameters "weave" into the fabric of the registers
used to process data.

Since this is an assembly language group, let me put it in assembly
language terms. If you are constructing a call in assembly language, you
are going to construct the code before a routine call with an eye towards
the coming call. You will arrange the registers used so that they don't
interfere with the registers needed for parameters, and you will arrange
calculations that end up in parameters to occupy the same registers as
the assigned parameter registers. At the top of the routine, you will
avoid the registers that hold parameters as long as possible, or store
the parameters whose registers absolutely must be used. You will try
to perform calculations that use parameters first, so that the registers
involved can be reused. You will try to structure the code so that the
passed parameter registers can be used, without moving them, then
discarded.

In short, in a high performance compiler, the rules are simple: register
allocation is the first and most important principle of code efficiency.

-- 
Samiam is Scott A. Moore

Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas

Being right is more powerful than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.

0
Scott
8/15/2004 7:26:15 AM
Grumble wrote:
> Jonathan Bartlett wrote:
> 
>> You cannot pass "structs" as arguments in C, unless that changed
>> in C99.  You can only pass pointers to structs in C.
> 
> 
> ??

I looked it up.  It turns out that this restriction is limitted to K&R.

Jon

0
Jonathan
8/16/2004 7:12:07 PM
Scott Moore <spamtrap@crayne.org> wrote:
> Indeed, this is what happened when many of the low performing
> compilers of the 1980's tried to use register passing
> conventions. This was used as "proof" that the register based
> calling conventions don't "work".

This is very odd, since on an 8088, register calling
conventions should give a substantial boost, even with a bit of
`xchg` register swizzling, because of the very choked memory
bus.  Even a 286 and 386 probably benefitted from reg-call.
Only on the 486 with fast internal cache did it begin to make
less difference.

> The difference is
> that a very advanced compiler can plan both the approach
> to the call, and the sequence at the top of the routine,
> so that the registers used for parameters "weave" into the
> fabric of the registers used to process data.

Whence the complaint about a shortage of registers.

> calculations that end up in parameters to occupy the same
> registers as the assigned parameter registers. At the top

This should be something a compiler can do easily.
Pre 386, the registers were more purpose-bound, but
`xchg ax,_x` was always fast.

> In short, in a high performance compiler, the rules are
> simple: register allocation is the first and most important
> principle of code efficiency.

I'm not sa compiler writer, but it seems to me that keeping
all the issue ports and execution pipes working in parallel
is most important.  Maximum parallelism.

-- Robert

0
Robert
8/17/2004 2:57:31 AM
Scott Moore wrote:

> Matt Taylor wrote:
> 
>> Scott Moore wrote:
>>
>>> The registers used to pass parameters can vary. The convention may
>>> use the stack for parameters. It may use registers. It may use
>>> a combination of both. The function result can be contained in a
>>> register, or it may be on the stack. Registers may be specified
>>> as preserved by the caller, callee, or a combination of both. There
>>> are even compilers that pass the parameters in fixed global locations.
>>>
>>> There is no such animal as a "universal" C calling convention.
>>
>> Anyone who wans to dispute this statement should post (and
>> subsequently get flamed for being "off-topic") on comp.lang.c.
>> The "C" calling convention is just a Microsoft misnomer.
>> AFAIK it is the same as the System V calling convention.
> 
> Fine. Please quote where in the white book on C, or in the ANSI standard
> on C, does it specify the assembly language details of C calls ?
> 
> Again, no such animal. System V is only one calling convention, was
> produced by AT&T, and is neither standard, nor binding on anyone.
> 
> NO high level language specifies its assembly level details. Thats why
> they call it a "high level language".

It seems to me that Matt was agreeing with you...

0
Grumble
8/31/2004 9:34:14 AM
Jonathan Bartlett wrote:

> Grumble wrote:
> 
>> Jonathan Bartlett wrote:
>>
>>> You cannot pass "structs" as arguments in C, unless that changed
>>> in C99.  You can only pass pointers to structs in C.
>>
>> ??
> 
> I looked it up.  It turns out that this restriction is limited to K&R.

Where have you been for the past 15 years? :-)

0
Grumble
8/31/2004 9:51:44 AM
>>- 4 byte floating point no's pushed onto stack as single DWORDs
>>
> 
> Except when dealing with variable-argument functions, here 4-byte
> floating point values (real4, float, whatever) will be promoted to
> 8-byte double (I believe this is standardized C behaviour, too lazy
> to look it up in the reference though.)
> 

Thank you, I hadn't even begun thinking about vararg calls yet :-)

You mention "the reference". I spent quite a bit of time googling for an 
authoritative source on calling conventions and never really found 
anything. Who is the keeper of "the reference"?

Mike

0
Mike
9/13/2004 11:10:03 AM
Mike wrote:

> You mention "the reference". I spent quite a bit of time googling for
> an authoritative source on calling conventions and never really found
> anything. Who is the keeper of "the reference"?

AFAIU, calling conventions are implementation-dependent. In other words,
check your platform's documentation (architecture, OS, compiler).

-- 
Regards, Grumble

0
Grumble
9/13/2004 12:02:47 PM
Tim Roberts <spamtrap@crayne.org> wrote:
> gcc on Linux pushes right-to-left, caller fixes the stack.
> That's identical to the Windows standard.  What is it that
> you mean by "AT&T convention"?

caller fixup only makes sense with functions that take
variable numbers of params, like `printf`.

Right-to-left is more arbitrary and irrelevant for `c` callees,
but works a little better for ASM callees.  Imagine adding a
new param to a call.  Most likely at the right.  Patching the
asm is just adding references to the new [EBP+xxx].  No fixup
for existing parms which would be required if new parm added
at left or order was left-right.

-- Robert

0
Robert
9/16/2004 11:10:00 AM
"Robert Redelmeier" <redelm@ev1.net.invalid> wrote in message
news:sRoTc.228$Jt4.136@newssvr24.news.prodigy.com...

>
> Right-to-left is more arbitrary and irrelevant for `c` callees,
> but works a little better for ASM callees.  Imagine adding a
> new param to a call.  Most likely at the right.  Patching the
> asm is just adding references to the new [EBP+xxx].  No fixup
> for existing parms which would be required if new parm added
> at left or order was left-right.
>
> -- Robert
>

Robert, if you're using an assembler that forces you to
access local objects and parameters in this fashion, you
might want to consider switching assemblers.
At the very least, use equates so that you only have to
make the change in one place.

It's been a *long* time since x86 assembly language
programmers have been forced to maintain their
programs in the manner you describe (even using
equates).
Cheers,
Randy Hyde

0
Randall
9/16/2004 4:18:43 PM
On Mon, 13 Sep 2004 11:10:03 +0000 (UTC), Mike  <spamtrap@crayne.org>
wrote:

> >>- 4 byte floating point no's pushed onto stack as single DWORDs
> >>
> > 
> > Except when dealing with variable-argument functions, here 4-byte
> > floating point values (real4, float, whatever) will be promoted to
> > 8-byte double (I believe this is standardized C behaviour, too lazy
> > to look it up in the reference though.)
> > 
> 
> Thank you, I hadn't even begun thinking about vararg calls yet :-)
> 
> You mention "the reference". I spent quite a bit of time googling for an 
> authoritative source on calling conventions and never really found 
> anything. Who is the keeper of "the reference"?
> 
As already said there is no single reference for calling conventions.

The C standard does provide that for varargs, and for unprototyped aka
old-style or K&R1 calls all args, values of integer types 'below' int
(char and short, both signed and unsigned forms, and bitfields) are
promoted to (signed) int -- or in some cases unsigned int, which are
required to be the same size and mostly though not completely the same
layout -- and 'float' is promoted to 'double'. Those aren't required
to be 4-byte and 8-byte specifically, but they are required to support
precision and range which in practice usually works out to that.

- David.Thompson1 at worldnet.att.net

0
Dave
9/20/2004 5:38:55 AM
Reply: