gcc and registers

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
dumaisp
Posts: 13
Joined: Fri Feb 15, 2008 8:58 am

gcc and registers

Post by dumaisp »

Hi,

I have an asm file and a C file that I compile like this:
gcc -m32 -c process.s
gcc -m32 -c mem.c
ld process.o mem.o .........

in process.s I call functions from mem.c.
At home I compile this using GCC4 and when I disassemble mem.o (the one writtin in C), I notice that only the EAX register is being used. That is fine, I rely on that because in process.s I don't want the other registers modified.

But now I compile this using GCC3.4.6 and I noticed that my function uses ECX and EDX without even pushing and poping them and at the end. So the function in process.s cannot assume that the registers it uses will still be correct after calling a function written in C.

Obviously, it is better when it uses several registers instead of memory, but it should push/pop them?

Any one have a solution for this, other than pushing my registers before calling the function? There must be a flag I could set with gcc.
User avatar
jerryleecooper
Member
Member
Posts: 233
Joined: Mon Aug 06, 2007 6:32 pm
Location: Canada

Post by jerryleecooper »

I am no expert on this, but I believe that in C, you can't expect your registers to hold valid data after a function call. So you need to push/pop from the function calling your C function.

Did you try to use gcc 4 ( i didnt know it existed) with optimizations on, -O2, for example?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

There are several general purpose registers: EAX, EBX, ECX, EDX, ESI and EDI.

Three of these are also called 'scratch registers': EAX, ECX, EDX. These, according to the __cdecl calling convention, are not required to be maintained across a function call. So the caller may never assume these registers to have the same value on return as when called.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: gcc and registers

Post by jal »

dumaisp wrote:Any one have a solution for this, other than pushing my registers before calling the function? There must be a flag I could set with gcc.
I don't think so. GCC does not assume any registers are being saved accross function calls, except for the obvious ones (ESP and EBP). All general purpose registers (EAX, EBX, ECX, EDX, ESI, EDI) may be trashed. EAX holds the return value if it's a non-void function. If there is a flag, check the GCC manual pages.

EDIT: JamesM already provided a more detailed answer. It seems only EAX, ECX and EDX may be trashed.

JAL
dumaisp
Posts: 13
Joined: Fri Feb 15, 2008 8:58 am

Post by dumaisp »

Oh, I found this on another thread:
http://www.asmtrauma.com/Articles.htm

Very good documentation.

I find it odd though, the routine should clean itself up. i.e. save/restore all modified registers and clean the stack after. It's like saying: I'm gonna do the dishes before I eat instead of after i'm done eating.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

save/restore all modified registers
It does. All except the scratch registers.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

dumaisp wrote:I find it odd though, the routine should clean itself up.
No it shouldn't. The caller knows which registers are still needed and which ones could be trashed, so I'm quite OK with the caller saving what it still needs before calling a function. This is thinking beyond x86, mind you.

Cleaning up the stack done by the callee could become problematic when you think about varargs...
Every good solution is obvious once you've found it.
Post Reply