Search code examples
assemblyarmthumbcortex-m

ARM Cortex M0/M3/M4:Why PC is always Even number in Thumb State


As far as I understand it, ARM Cortex-M CPUs are always in Thumb state, which means:

Thumb state indicated by program counter being odd (LSB = 1). Branching to an even address will cause an exception, since switching back to ARM state is not allowed.

However, while I am using CortexM0 and M4 CPU, the PC is always even. Each time I branch, the LR records PC+1 and each time I return, the PC gives LR-1.

For example, if lr = 0x0000_01D5,

Execute

BX lr

Then PC should be 0x0000_01D5, whereas it gives 0x0000_01D4.

Isn't this impossible?

Any comment will be appreciated.


Solution

  • From Cortex-M4 Technical Reference Manual:

    2.3.1 Program counter

    Register R15 is the Program Counter (PC).

    Bit [0] is always 0, so instructions are always aligned to word or halfword boundaries.

    Reading from PC shouldn't return an odd address. However when you write to PC, LSB of value is loaded into the EPSR T-bit. From Cortex-M3 Devices Generic User Guide - 2.1.3. Core registers

    Thumb state

    The Cortex-M3 processor only supports execution of instructions in Thumb state. The following can clear the T bit to 0:

    instructions BLX, BX and POP{PC}
    
    restoration from the stacked xPSR value on an exception return
    
    bit[0] of the vector value on an exception entry or reset.
    

    Attempting to execute instructions when the T bit is 0 results in a fault or lockup. See Lockup for more information.

    In other words, you can read even values from PC but can't write such values under normal circumstances.