2
votes

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

2
related: What registers are preserved through a linux x86-64 function call all of the arg-passing registers are always call-clobbered. And What are callee and caller saved registers?. 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

2 Answers

8
votes

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.

6
votes

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.