Arm mode and Thumb mode makes the PC's bit 0

The ARM and Thumb modes are word-aligned and halfword-aligned. I understand this means that if it's in ARM mode, the start of addresses must be divisible by 32, and if it's in Thumb mode it has to be divisible by 16. But how does this relate to the PC's bit 0 never used for anything? (The instructor said that because of that they used PC's bit 0 to show whether it's in thumb or ARM mode since it wasn't being used for anything else, but before that I'm confused about the relation between alignment and PC's bit 0)

• It's a common confusion that bit 0 of the PC stores the thumb state. In fact it does not - that is in bit T of the CPSR. What is true is that that bit 0 of the destination address of vectors and certain branches determines the mode to be used on reaching the destination, but that bit is masked before loading into the PC. – Chris Stratton Mar 18 '17 at 19:16

The bx instruction copies bit 0 to the T status bit, so it selects between ARM and Thumb mode on branch.

mov r0, 0
bx r0


mov r0, 1
bx r0


mov r0, 3
bx r0


ARM code cannot exist at address 2, because that would violate the alignment constraint. Neither ARM nor Thumb code can start at odd addresses, so the LSB of the address is always zero, and the bit is reused to select the new mode in the bx instruction.

To allow easy return from subroutines, bit 0 of the lr register reflects the Thumb state from before the function call after a blx instruction. So:

    mov r0, #2f
blx r0
1:
b 1b

.thumb
2:
bx lr


will load the address of the 2 label with the bit 0 set (as the label refers to Thumb code) into r0, then blx loads the address of the l label with bit 0 clear (because it refers to ARM code) into lr and jumps to the bx lr instruction, which uses the lr to return to the endless loop in ARM mode.

• Thank you! I'm confused by your first three examples of jumping to address 0-2. Do you mind going over that in more detail? Why would it have to start from address 0? Rather than address 0 + 2? – stumped Mar 18 '17 at 19:12
• The mov loads the address, and the bx jumps, using the top 31 bits for the PC and the bottom bit as the new Thumb state, so the address is one larger than the actual target address if you also switch to Thumb mode. – Simon Richter Mar 18 '17 at 19:17
• I'm sorry for being unclear. I meant I'm confused on why the address has to start at address 0. Couldn't it start at address 4, and satisfy ARM and thumb alignment? – stumped Mar 18 '17 at 19:18
• Sure, any address divisible by 4 satisfies both alignment requirements, so you can have Thumb code there as well. – Simon Richter Mar 18 '17 at 19:20
• Indeed. The special treatment for Thumb mode is only in the blx instruction (and ldr pc, ... and ldm {..., pc}, ... on most, but not all cores that have Thumb support). – Simon Richter Mar 18 '17 at 19:25

I understand this means that if it's in ARM mode, the start of addresses must be divisible by 32, and if it's in Thumb mode it has to be divisible by 16.

No; this means that in ARM mode, instructions must start at an address divisible by 4, or divisible by 2 in Thumb mode.

Numbers that are divisible by 4 are also divisible by 2.

Numbers that are divisible by 2 are even; they always have their low bit (bit 0) set to 0.

• Thank you for the correction! Although I'm still confused on why the LSB is set to 0 – stumped Mar 18 '17 at 18:57
• Yeah, this should really be a comment. You're not answering the question, simply pointing out a simple mistake in the question body (confusing bits and bytes) – pipe Mar 18 '17 at 18:58
• @pipe The OP was missing the connection between even numbers and a zero LSB. That's the link I was trying to draw in my answer. – duskwuff -inactive- Mar 18 '17 at 19:44