Passing a stack frame by value
Posted: Fri Sep 20, 2019 1:57 am
I spent about three hours yesterday debugging an issue triggered by a gcc optimisation. I'm posting it in the hope that it may save someone some time. Basically, my ISR look like this:
where handler is the following C function:
Obviously (in retrospect), this is wrong, because the compiler is free to elide any modifications to stack that the function makes (and indeed it did so when compiling with -O2).
I wonder if there is a way to beat the compiler into submission by explaining that the stack is going to be valid after the call. For example, adding a call to an empty function (defined in another compilation unit!) that takes a pointer to the stack as argument does the trick, but I don't think it's guaranteed to. I guess the calling convention makes no guarantees about the validity of the arguments on the stack after the call, so I should probably give up and pass the stack frame by reference, shouldn't I?
Code: Select all
...
pusha
call handler
popa
...
iret
Code: Select all
void handler(isr_stack_frame_t stack)
{
/* possibly do something to the stack */
}
I wonder if there is a way to beat the compiler into submission by explaining that the stack is going to be valid after the call. For example, adding a call to an empty function (defined in another compilation unit!) that takes a pointer to the stack as argument does the trick, but I don't think it's guaranteed to. I guess the calling convention makes no guarantees about the validity of the arguments on the stack after the call, so I should probably give up and pass the stack frame by reference, shouldn't I?