2

I'm writing some x86_64 assembly to call a C function. My C function takes in 1 argument, so the assembly places the argument in %rdi. The ABI pdf (linked below) says that the other 6 argument registers (rsi, rdx, rcx, r8, r9) are not preserved across function calls. However, since my C function only takes one long argument, do I have any guarantees about whether or not the C function will clobber the other 5 registers? My assumption was that the argument registers are only clobbered if an argument's value is changed:

void foo(int a, int b) {
    a++; /* %rdi will be changed, but %rsi won't be changed when control returns. */
}

I'm asking because I'd like to preserve the values of the other 5 argument registers across my C function call (without having to explicitly push/pop them from the stack manually).

x86_64 ABI - http://www.x86-64.org/documentation/abi-0.99.pdf

Chris
  • 2,786
  • 1
  • 28
  • 31
  • related: [What registers are preserved through a linux x86-64 function call](https://stackoverflow.com/q/18024672) all of the arg-passing registers are always call-clobbered. And [What are callee and caller saved registers?](https://stackoverflow.com/q/9268586). Compilers will use call-preserved registers like RBX - save it once, then use it to let things survive as many function calls as you want. – Peter Cordes Apr 08 '21 at 00:48

2 Answers2

8

There is no guarantee. You will have to save them on the stack to ensure they are not changed. Whether they are changed will depend on the compiler.

If you want to somehow ensure they are not changed, you could write the function in assembly.

ronalchn
  • 12,225
  • 10
  • 51
  • 61
  • There's no guarantees that the function being called is well-behaved. But we should be able to make that assumption that it is which is the point of the ABI. – Jeff Mercado Sep 01 '12 at 01:46
  • Another common way to save values across function calls is in call-preserved registers. x86-64 calling conventions have a good mix of call-preserved and call-clobbered, so functions that make more than one function call can keep a value in a register without saving/restoring it all the time. – Peter Cordes Oct 24 '22 at 10:10
7

Look at the table on page 21. It has a column "Preserved Yes/No" for all the registers. And it says "No" for all the registers used to pass parameters.

Whether you pass arguments or not, the argument registers are not required to be preserved. You will likely not get your parameters back.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203