Octocontrabass wrote:Speaking of the stack, be careful to keep the stack properly 16-byte aligned when you call a C function. (If your pushall macro pushes 15 registers, the stack will be correctly aligned. Each value you push moves the stack by 8 bytes, and the interrupt itself pushes five values before running your handler code, for a total of (15+5)*8=160 bytes.)
We're going a bit off topic but I'd like to get some clarification on this particular point.
The only reference to 16-byte stack alignment I could find in the x86_64 ABI specifically mentioned 16-byte alignment for the initial %rsp value of a new process (section 3.4.1 of the ABI). It's not unreasonable to extrapolate that to mean that any function entry point should have a 16-byte stack alignment, so let's use that assumption.
Any compiled code (C, etc.) should do this automatically. But if I have assembly code in my kernel that calls a C function, I should actually align the stack as 8-byte aligned, but NOT 16-byte aligned, so that the 'call' instruction pushing the return address on the stack will result in the C function entry point getting a 16-byte aligned stack.
In other words, I should wrap all my asm->C calls with either a macro or a wrapper function that makes an extra adjustment to the stack (if necessary) and restores it after the call. (update: alternatively, I could use the logic the compiler uses, which is that I should know at all times how the stack is aligned, because I generated the instructions that manipulate it, so I may only need realignment in a few very specific places).
Do I have that right?