I am working on an ARM Cortex-M4 processor using IAR Embedded Workbench. When the main stack overflows I get a bus fault. I have therefore written a small function in assembly to check if the bus fault was caused by a stack overflow, set the stack pointer and call a dedicated stack overflow handler.
The following code shows the function and it works fine. My problem is that I had to subtract 1 from the labels in the two LDR instructions and I don't understand why.
StackBegin: DC32 SFB(CSTACK) ; Start of main stack
StackEnd: DC32 SFE(CSTACK) ; End of main stack
BusFault_Handler:
LDR R0, StackBegin-1 ; No idea why we need to subtract 1
CMP SP, R0
IT GT
BGT BusFault_Post_Handler ; Call if SP is OK
LDR SP, StackEnd-1 ; On stack overflow, set SP to top of main stack; No idea why we need to subtract 1
B MainStackOverflow_Handler
If I don't subtract 1, the LDR instructions load data one byte after the label. StackEnd contains the value 0x20000400, but SP is loaded with 0x5F200004 unless I subtract 1 from the label. The 0x5F is the first byte in BusFault_Handler.
Can anyone explain why I need to subtract 1. Have I configured something wrong. I have checked that the data is word (4 byte) aligned.