6
votes

ARM Cortex-M cores documentation says, that upon an exception entry stack framing is performed. This causes registers R0, R1, R2, R3, R12, LR, PC, xPSR to be pushed onto the current stack. My question is 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.

Compiled function of an exception handler itself pushes some registers (as well as every other regular function, because exception handler function is no difference), but after a lot of debugging I came across the fact that it is not always a case, because different variations of registers are pushed and then restored.

1

1 Answers

10
votes

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

To improve interrupt response time. Fewer stack operations means the handler can start faster.

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

Then it is the responsibility of the handler to save 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)

That's intentional. A called function must preserve the same set of registers as an interrupt handler (R4-R11, and SP). So, if a normal function wants to use R5, it must as well save it somewhere and restore it later (see the Procedure Call Standard for the ARM® Architecture for details). That way, a compiler can treat interrupt functions the same way as normal functions.

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

If a compiled function overwrites a register in the R4-R11 range without saving and restoring it, or does not properly restore PC or SP, then your compiler is broken, period.