This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Resetting the stack pointer in "noreturn" functions?

Architecture: Cortex-M0

Toolchain: gcc-arm-none-eabi-6-2017-q2-update, gcc-arm-none-eabi-8-2018-q4-major

In an attempt to mitigate the possibility of stack overflow I would like to reset the stack pointer after entering a function that will never return. There are two cases in my code where this occurs, main() and a shutdown() ISR that saves data to flash and enters deep sleep. I use LTO to make the code fit, so main() ends up being quite a large function that requires allocating part of the stack for local variables. My first attempt was to use the "noreturn" attribute combined with a call to  __builtin_unreachable(), but that does not change the generated assembly in any way. I then created an inline assembly function to reset the stack pointer to the last SRAM address:

I then call this at the very beginning of main and the shutdown ISR:

This generates seemingly correct code for the ISR:

For main however the "mov sp, r3" happens after stack is allocated for local variables etc.. This will fail once main starts branching.

 Does anyone have any tricks for how this can be done correctly? I could always create a second variant of the NO_RETURN() function which takes a stack allocation value as an argument, compile, disassemble, compile again and insert the required "sub sp, #nn" after the "mov sp, r3", but that is a messy solution.

Bonus question: Why does the compiler generate the "ldr r3, [r3, #0]" instruction? "Load r3 into r3 with zero offset" sounds like a nop?

0