On a Cortex M0:
50: tmp=SST_PSI->BANK[2].PERID //should be 0x40050000
0x000006EA 480A LDR r0,[pc,#40] ; @0x00000714
...
0x00000712 1000 DCW 0x1000 0x00000714 0000 DCW 0x0000 0x00000716 4005 DCW 0x4005 0x00000718 B5F0 PUSH {r4-r7,lr}
This is not handwritten assembly, it's C compiled by Keil. It is generating a hard fault, but if the code is offset by 2 bytes (adding a nop in C) it does not.
From what I understand:
1. An LDR must have a word-aligned target, divisible by 4x 2. To correctly implement the PERID=0x40050000, LDR needs to target 0x00000714 3. The compiler-generated annotation says it's targeting 0x00000714 as expected 4. The target is the address of the LDR instruction, plus FOUR, plus the offset 5. Unfortunately, Cortex M0 lacks HFSR which would provide more info.
Well but the target does NOT add up to 714. 0x6ea+0x04+#40=0x716, which is not the correct word, and it's misaligned, which explains the hard fault.
When I add a nop into the code to move the whole code down by 2 bytes, it's NOT generating Hard Fault, but also the calculated target decodes to the 0x4005000 target data, and the compiler annotation target agrees with the calculated target.
What's going on here? Do I have this right? Is Keil generating a misaligned word access? But it also didn't actually PUT the data on the word-misaligned addr, and its annotations claim it's targeting a different address?
No, it's +4, but I missed something:
"In Thumb state: For B, BL, CBNZ, and CBZ instructions, the value of the PC is the address of the current instruction plus 4 bytes. For all other instructions that use labels, the value of the PC is the address of the current instruction plus 4 bytes, with bit[1] of the result cleared to 0 to make it word-aligned."
OK, that's a bit different then. The assembly is 16-bit instructions so we're talking Thumb-16.
So for: 0x000006EA 480A LDR r0,[pc,#40] ; @0x00000714
That would be 0x6ea+#4, then clearing Bit [1] (I missed that part) gets 0x6EC for the effective program counter. 0x6EC + #40 would be 0x714, which would be the correct target, and aligned.
Still leaves me with a problem here, just not what I thought.