ARM Cortex-M 异常入口和堆栈框架

ARM Cortex-M exception entry and stack framing

ARM Cortex-M 核心文档说,在出现异常入口时执行堆栈框架。这会导致寄存器 R0、R1、R2、R3、R12、LR、PC、xPSR 被压入当前堆栈。 我的问题是为什么这种方式只推送那些寄存器而不是所有上下文?例如,如果某些数据在 R5 寄存器中,则在异常处理程序使用该寄存器的情况下它将被覆盖。

异常处理程序的编译函数本身会压入一些寄存器(以及所有其他常规函数,因为异常处理函数没有区别),但经过大量调试后我发现情况并非总是如此,因为不同的变化的寄存器被压入然后恢复。

why it is this way to only push those registers and not all of the context?

改进中断响应时间。更少的堆栈操作意味着处理程序可以更快地启动。

For example, if some data was in R5 register, it will be overwritten in case exception handler uses that register.

那么处理程序负责保存R5。

Compiled function of an exception handler itself pushes some registers (as well as every other regular function, because exception handler function is no difference)

那是故意的。被调用函数必须保留与中断处理程序相同的一组寄存器(R4-R11 和 SP)。所以,如果一个普通的函数想要使用 R5,它也必须将它保存在某个地方并稍后恢复它(详见 Procedure Call Standard for the ARM® Architecture)。这样,编译器就可以像对待普通函数一样对待中断函数。

it is not always a case, because different variations of registers are pushed and then restored.

如果编译后的函数覆盖了 R4-R11 范围内的寄存器而没有保存和恢复它,或者没有正确恢复 PC 或 SP,那么你的编译器就坏了。