> In most cases, if a function modifies a non-volatile register, it'll save it to somewhere on the stack before modifying it. Upon function return, it'll re-load the value from said stack slot
Dumb question: is this a linux specific calling convention thing (I know prologue/epilogue don't mess with random registers, so i'm a bit confused)? Why shouldn't the caller save all the registers it needs instead of relying on the good behavior of the callee?
When I call certain syscalls (Linux/x64), if I have data in certain registers, the kernel does not preserve and restore the data but it garbles it up. Is there documentation/convention somewhere describing which registers are considered volatile by the ABI or do people find out the hard way normally?
> Why shouldn't the caller save all the registers it needs instead of relying on the good behavior of the callee?
You've got to rely on good behavior of the callee in general anyway. Calling conventions are part of the ABI and the caller and callee already need to agree on parameter passing (except for void(void) functions, which usually aren't much fun).
Picking which registers are callee saved and which are caller saved is roughly an optimization problem. Compilers don't have enough information to know what registers the callee (and its callees) actually use, so the caller can't save only the registers it has used that will definitely be trashed. Caller saving registers that the callee doesn't touch wastes code size, stack space, cpu time, and memory/cache bandwidth; same for callee saving registers the caller didn't need to be saved. So somebody puts together a convention that says these registers are super handy and most functions will want to use them --- those will be caller saved if necessesary. The other registers are deemed to be less likely to be used, callees will save them before using, just in case.
Syscalls may often have a different calling convention than library calls, because the needs are different.
> Why shouldn't the caller save all the registers it needs instead of relying on the good behavior of the callee?
The cost to save a register is non-zero so it's helpful to have some registers the caller doesn't have to preserve and that don't need to be saved by the callee if it won't be using them.
I had to figure all of this out a few years ago and would have really benefitted from the author's clear, precise take.
This is going into the onboarding docs for my team tomorrow morning.