Core behavior and first-principles view
Stack behavior defines call correctness on Cortex-M. Every push/pop choice and frame boundary must be consistent with ABI and interrupt interaction.
Function prologue/epilogue pattern preserves context and allocates local frame storage.
LR tracks return path and must be protected when nested calls occur.
Stack alignment constraints matter for ABI compatibility and exception handling.
Low-level model and equations
Stack pointer movement for n 32-bit pushes:
Where:
- : number of pushed registers/words
How to build this correctly in practice
- Verify each push has a matching pop path across all exits.
- Review function call depth and local storage for worst-case stack usage.
- Check stack alignment before and after call sequences.
- Combine static review with runtime watermark measurement on target.
Common failure patterns and review checks
- Mismatched save/restore sets corrupt return state quickly.
- Large locals can cause hidden stack pressure in deeply nested paths.
- Interrupt paths must be included in stack budget.
- Unbounded recursion is a stack-risk amplifier on microcontrollers.
Stack-safe firmware is engineered, not guessed: explicit frame accounting beats post-failure debugging.