public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* C/C++ Calling assembler
@ 2009-04-30 20:46 Michael
  2009-05-01 13:28 ` John Fine
  0 siblings, 1 reply; 3+ messages in thread
From: Michael @ 2009-04-30 20:46 UTC (permalink / raw)
  To: gcc-help

Hi

I want to call assembler routines from from C/C++ but am very confused at
the variation in calling conventions and how I can
force the complier to put arguments on the stack and not use registers, or a
combination, or do something else that isn't
deterministic that will screw up the assembler code.

I have tried using -mregparm=0 on the command line but that seems to screw
up calls to the standard library.

I have tried using unsigned char myfunction(unsigned char buf),
__attribute__ ((regparm(0))) after the function prototype

I have tried making the function prototype variadic.

An examination of the assembler produced always shows it passes the buffer
pointer in %edi and not on the stack.

Also, I am confused over whether the IP pushed is 32 or 64 bit in size. I
have read that the memory model used on linux limits
code and global data to 2GB each but dynamically allocated data can be as
large as you like, so code can be made more
compact.

What I would really like is some pointers to good documentation about all
this if it exists.

I use the Latest Ubuntu 64bit Linux and latest C++ compilers.

Any help or pointed would be very much appreciated.

Michael





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C/C++ Calling assembler
  2009-04-30 20:46 C/C++ Calling assembler Michael
@ 2009-05-01 13:28 ` John Fine
  2009-05-01 15:47   ` Bob Plantz
  0 siblings, 1 reply; 3+ messages in thread
From: John Fine @ 2009-05-01 13:28 UTC (permalink / raw)
  To: gcc-help; +Cc: Michael

Michael wrote:
> I want to call assembler routines from from C/C++ but am very confused at
> the variation in calling conventions and how I can
> force the complier to put arguments on the stack and not use registers, or a
> combination, or do something else that isn't
> deterministic that will screw up the assembler code.
>   

It is certainly deterministic and the x86-64 abi is documented, 
including details of which parameters go in which registers as well as 
which registers must be saved by the called routine (if used).

You may be better off learning that calling standard (it is very helpful 
to know when debugging C++ code) rather than trying to sidestep it.
> I have tried using -mregparm=0 on the command line but that seems to screw
> up calls to the standard library.
>   
As you would expect.
> I have tried using unsigned char myfunction(unsigned char buf),
> __attribute__ ((regparm(0))) after the function prototype
>   
I don't know.  I'd like to understand such features, so if some expert 
explains that, I'll learn something too. 
> An examination of the assembler produced always shows it passes the buffer
> pointer in %edi and not on the stack.
>   
?? %edi not %rdi ??

That would mean you are compiling 32 bit code.  I assume that is not 
what you intended.

But possibly with a statically allocated buffer, the compiler can deduce 
that the buffer will be in the first 4GB at run time and it can put the 
correct address into rdi more efficiently by moving it to edi (with 
implicit zeroing of the high 32  bits) than by moving it to rdi.
> Also, I am confused over whether the IP pushed is 32 or 64 bit in size.
If you are compiling for x86-64 then a call would push the 64 bit rip.  
If you are compiling for i386 through i686 etc. the 32 eip would be pushed.

>  I
> have read that the memory model used on linux limits
> code and global data to 2GB each but dynamically allocated data can be as
> large as you like, so code can be made more
> compact.
>
> What I would really like is some pointers to good documentation about all
> this if it exists.
>
> I use the Latest Ubuntu 64bit Linux and latest C++ compilers.
>
>   
Both the above statements tell me you intend to be compiling 64 bit 
code.  But I don't know for sure that you are compiling 64 bit code.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C/C++ Calling assembler
  2009-05-01 13:28 ` John Fine
@ 2009-05-01 15:47   ` Bob Plantz
  0 siblings, 0 replies; 3+ messages in thread
From: Bob Plantz @ 2009-05-01 15:47 UTC (permalink / raw)
  To: John Fine; +Cc: gcc-help, Michael

On Fri, 2009-05-01 at 09:28 -0400, John Fine wrote:

> > An examination of the assembler produced always shows it passes the buffer
> > pointer in %edi and not on the stack.
> >   
> ?? %edi not %rdi ??
> 
> That would mean you are compiling 32 bit code.  I assume that is not 
> what you intended.
> 
> But possibly with a statically allocated buffer, the compiler can deduce 
> that the buffer will be in the first 4GB at run time and it can put the 
> correct address into rdi more efficiently by moving it to edi (with 
> implicit zeroing of the high 32  bits) than by moving it to rdi.

Yes, apparently the compiler does this. It will, for example, put
constants like text messages in a "small memory" area and pass the
address in the 32-bit portion of the register. Because changing the
32-bit portion of the register always zeros the high-order 32 bits, this
results in a correct 64-bit address. The main saving here is that the
instruction to access edi does not require a REX prefix byte, but rdi
does.

Aside: changing 8 or 16 bits in a register does NOT affect the other
portions of the register.

Bob


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-05-01 15:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-30 20:46 C/C++ Calling assembler Michael
2009-05-01 13:28 ` John Fine
2009-05-01 15:47   ` Bob Plantz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).