0

Thumb-2 have 32 and 16 bits instruction sizes that are aligned to 2 bytes. Moreover when an instruction is executed the PC register has the value of the two instructions ahead of it. That is when you type :

    0x1 - MOV R1, [PC #xx]

The PC value is not 0x1, but 0x1 + the size of the two instructions ahead, so in the case of :

  • Two 16 bits instructions : PC = 0x1 + 4
  • One 16 bits and one 32 bits instruction : PC = 0x1 + 6
  • Two 32 bits instruction : PC = 0x1 + 8

That was the theory (correct me if I'm wrong). But in my assembly code, I've got weird things : Here when 0x1AE is executed PC is equal to 0x1EC - 60, that is 0x1B0, so the PC has just been incremented by 2.

    0x1AE 490F      LDR      r1,[pc,#60]  ; @0x1EC
    0x1B0 6008      STR      r0,[r1,#0x00]
    0x1B2 F7FFFFE9  BL.W     dly (0x08000188)

And here with a similar scenario when 0x1D4 is executed PC is equal to 0x1F0 - 24, that is 0x1D8, so the PC has been incremented by 4.

    0x1D4 4906      LDR      r1,[pc,#24]  ; @0x1F0
    0x1D6 6008      STR      r0,[r1,#0x00]
    0x1D8 F7FFFFD6  BL.W     dly (0x08000188)

I'm confused with this PC behaviour, this Thumb-2 assembly code seems illogical to me. Could you explain me why this happen and what I don't understand with the Thumb-2 PC register behaviou. It should have a logic because compiler know at compile time the PC value.

  • Have a look at the ARM reference manual for the processor you are programming for. This should clear up all questions you might have. – fuz May 06 '20 at 12:42
  • 2
    [About arm pc value in thumb 16/32bits mixed instructions stream](https://stackoverflow.com/q/29586536) says it's a flat `+4` in thumb mode, regardless of instruction size. Also note that `bl.w` is really 2 machine instructions, because it's part of Thumb-1 which only had 16-bit instructions. – Peter Cordes May 06 '20 at 12:50
  • And I think I confirmed that experimentally as you can as well, the processor would have to decode the instruction it is in and start to decode the next instruction before executing to determine the offset to the lr. sticking with the pre-thumb2 days of just add 4 makes a whole lot more sense, esp with the tiny pipelines in some of the implementations. so +4 seems like it would be the right answer....and is. – old_timer May 06 '20 at 14:44
  • sorry it would have to decode two instructions ahead to determine the size of each, +4, +6 or +8. before executing the current instruction. some of these implementations only fetch 16 bits or 32 bits at a time so that would be extra costly. – old_timer May 06 '20 at 14:48

0 Answers0