GCC does not save / restore reserved registers when calling functions

My script in GCC is causing me problems. The behavior that I get is not the behavior that I expect. To summarize the situation, I propose several new instructions for x86-64, which are implemented in a hardware simulator. To test these instructions, I take the existing C source code and manually encode the new instructions using hexidecimal. Since these instructions interact with existing x86-64 registers, I use I / O / clobber lists to declare dependencies for GCC.

What happens if I call a function, for example. printf, dependent registers are not saved or restored.

for example

register unsigned long r9 asm ("r9") = 101; printf("foo %s\n", "bar"); asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) ); 

101 was assigned r9, and the built-in assembly (fake in this example) depends on r9. This is done correctly in the absence of printf, but when it is, GCC does not save or restore r9, and by the time my user instruction is called, a different value appears.

I thought that maybe GCC might have secretly changed the assignment to r9, but when I do,

 asm volatile (".byte %0" : /* no output */ : "q" (r9) ); 

and look at the assembly, it really uses% r9.

I am using gcc 4.4.5. What do you think might happen? I thought that GCC would always save and restore registers when calling functions. Is there a way I can enforce it?

Thank!

EDIT: By the way, I am compiling a program like this

 gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test 
+2
c assembly gcc gas register-allocation
Jul 28 '11 at 17:20
source share
2 answers

ABI , section 3.2.1 says:

The registers% rbp,% rbx and% r12 through% r15 β€œbelong” to the calling function and are called to preserve their values. In other words, the called function must store these value registers for its caller. The remaining registers "belong" to the called function. If the calling function wants to store such a register value through a function call, it must store the value in its local stack frame.

therefore, you should not expect registers other than% rbp,% rbx, and% r12 through% r15 to be saved by calling the function.

+7
Jul 28 '11 at 17:52
source share
β€” -

gcc will not make variables with an explicit register, such as saved. Basically, this register notation you use makes the variable a direct alias for the register, provided that you want to be able to read back the value that is called in the register. If you used the register registered with the called party and not the register recorded with the call (with the caller saved), the problem will disappear.

+2
Jul 28 '11 at 17:50
source share



All Articles