The routine subs pc, lr, #4
arrow for register PC
the value of register LR
(which as mentioned is zero) minus the immediate #4
ie in the next cycle the processor must summarize execution from LR - 4
which is an invalid address, so SEGFAULT
.
The steps to be taken to safely enable IRQ
faults described in ARM documentation are:
Construct the return address and save it on the stack of IRQ
mode.
Save required registers and SPSR
of IRQ
mode.
Identify and clean the source of the interrupt.
Switch to System
mode while keeping IRQ
s disabled.
Check if the stack is aligned to eight bytes and adjust if necessary.
Save LR
from User
mode and setting, 0
or 4
to ARMv4
or ARMv5TE
, used in SP
of User
mode.
Enable interrupts and call the interrupt tracer function.
When the tracer function returns, disable interrupts.
Restore LR
of% mode User
and stack heap value.
Reset the stack if necessary.
Switch to IRQ
mode.
Restore the other registers and SPSR
of IRQ
mode.
Return from IRQ
.
In short: Make sure you're using the LR
value in the right way and you're not overwriting it anywhere.
Important: The return of an interrupt is different from the return of a function because the PC
holds the address of the next statement to be executed and in an exception / interrupt the value of PC
is copied to LR_<mode>
so if you skipped to that value the instruction referenced by this address would never be executed, so that is the subtraction ( LR - 4
).