ARM Technical Support Knowledge Articles

Why do I get a fault when I load a literal value and then branch to it?

Applies to: Cortex-M3


Various ARM architectures support 'interworking', which is the ability to switch between instruction sets (traditional ARM 32-bit instruction set or compressed 16-bit Thumb (possibly including extended Thumb-2) instruction set, at certain kinds of branches. This allows code routines implemented in alternate instruction sets to interoperate, by informing the processor of the change of instruction set at the branch.

The mechanism for switching makes use of the fact that all instructions must be (at least) halfword-aligned, therefore bit[0] of the branch target address is redundant. Therefore this bit can be re-used to indicate the target instruction set at that address. '0' means ARM, a '1' means Thumb (or Thumb-2).

For example, consider the instruction:

  BX lr

If the value in 'lr' is 0x20000000 then the processor will branch to the instruction at 0x20000000 and interpret it as an ARM 32-bit instruction.

If the value in 'lr' is 0x20000001 then the processor will branch to address 0x20000000 but interpret the instruction found there as a Thumb or Thumb-2 opcode.

ARM tools ensure that all branch target label addresses have bit[0] set correctly to represent the type of opcode found at that address. However, if the programmer created an address manually, for example by loading a literal constant into the register and then branching to it, he must take care of ensuring that bit[0] is correctly set to represent the opcode type of that branch target.

The Cortex-M3 processor supports only the Thumb-2 instruction set (a superset of traditional Thumb). Therefore all branch targets should be indicated as odd numbers, having bit[0] SET for interworking, indicating Thumb-style opcodes.

Manually created branch targets must be manually set to the actual target address + 1.

Attempting to branch to an even numbered address on Cortex-M3 using an interworking branch instruction will result in a Usage Fault of type INVSTATE.

Rate this article

Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential