2

I am interested in the ARM and Thumb2 commands: LDR and LDR.W, PC, =ADDR for absolute jumping to a certain address.

For example, when I jump from ARM code to ARM, the command LDR PC, =ADDR is performed. But what happens in the other scenarios?

from ARM to Thumb2

from Thumb2 to Thumb2

from Thumb2 to ARM

when is +1 needed to be added to the address? and why?

Halastra
  • 41
  • 1
  • 7

2 Answers2

3

The rule is actually quite simple:

  • If bit 0 of the address is 0, the CPU will execute the code as ARM code after the next branch
  • If bit 0 of the address is 1, the CPU will execute the code as Thumb after the next branch
  • Of course if there is a mismatch, the CPU will certainly get a fault (After executing random code) because it has no way to check if the code is ARM or Thumb.

This is what explains the +1.

Note that depending on the compiler, and depending on the label used, bit 0 of the address may be automatically set by the compiler.

Cquast
  • 58
  • 7
Dric512
  • 3,525
  • 1
  • 20
  • 27
  • Does that mean that `| 1` would be a better suffix than `+ 1`, in case the compiler has already adjusted the address? – John Burger Jun 18 '16 at 11:57
  • Yes, except that it might hide that the compiler as already set it and the OR is useless. – Dric512 Jun 18 '16 at 20:01
  • 1
    So: either a superfluous `OR`, done at _assembly_ time; or a hideous crash due to executing the wrong type of code. I think i know what I'd rather... – John Burger Jun 19 '16 at 01:55
1

You need to just read the documentation.

The following instructions write a value to the PC, treating that value as an interworking address to branch
to, with low-order bits that determine the new instruction set state:
— BLX (register), BX , and BXJ
— LDR instructions with <Rt> equal to the PC
— POP and all forms of LDM except LDM (exception return), when the register list includes the PC
— in ARM state only, ADC , ADD , ADR , AND , ASR (immediate), BIC , EOR , LSL (immediate), LSR (immediate), MOV ,
MVN , ORR , ROR (immediate), RRX , RSB , RSC , SBC , and SUB instructions with <Rd> equal to the PC and without
flag-setting specified.

Since you mentioned thumb2 that means armv6 or newer. (did you say thumb2 and generically mean thumb?) and I believe the docs are telling us the above applies for armv6 and armv7.

Note that bit is consumed by the instruction, the pc doesnt carry around a set lsbit in thumb mode, it is just used by the instruction to indicate a mode change.

Also note you should think in terms of OR 1 not PLUS 1. If you write your code correctly the toolchain will supply you with the correct address with the correct lsbit, if you add a one to that address you will break the code, if you are paranoid or have not done it right you can OR a one to the address and if it has it there already no harm, if it doesnt then it fixes the problem that prevented it from being there. I would never use a plus one though with respect to switching to thumb mode.

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • Yes, I will agree that the psuedo code in the arm documents are wrong, they do have cut and paste errors going on with respect to these bits. They almost always have though. – old_timer Jun 17 '16 at 20:50