armcortex-mthumb

How is this ARM (Thumb) LDR Instruction being calculated?


The code is running on a Cortex M0+. I am trying to calculate the addresses of LDR PC-related loads and am finding the addresses are not always consistent.

This LDR PC-related load does not follow any of the other LDR PC-related loads I have calculated so far. How was this address calculated step-by-step? Kindly, please provide supporting documentation as I have not seen this documented anywhere.

"Add 4 here", "Add 8 here", "use the next PC" are the typical answers however I am finding those answers do not provide consistent or correct results.

Here is the (Thumb) LDR instruction

ldr r3, [pc, #4] ;

enter image description here

Thumb instruction definition for a PC-relative load (ignore the highlight)

enter image description here

enter image description here

enter image description here

Edit:

Here are correct calculations.

Example 1: 0x1000'0306: LDR.N R4, [PC, #0xc0]

Wrong Calculated Address: 0x1000'0306 + 0x4 + 0xc0 = 0x1000'03CA

Correct Calculated Address: 0x1000'0306->clear bit[0]->0x1000'0304 + 0x4 + 0xc0 = 0x1000'03C8

enter image description here

Example 2: 0x1000'0306: LDR.N R4, [PC, #0xc8]

Wrong Calculated Address: 0x1000'0306 + 0x4 + 0xc8 = 0x1000'03D2

Correct Calculated Address: 0x1000'0306->clear bit[0]->0x1000'0304 + 0x4 + 0xc8 = 0x1000'03D0

enter image description here


Solution

  • The excerpt you quote seems to explain it pretty clearly, paying attention to the Notes: Add 4 to the address of the ldr instruction, clear bit 1 of the result, and add the immediate.

    In this example:

    Which agrees with what the disassembler is telling you.