I was debugging some c++ code (WinCE 6 on ARM platform), and i find some behavior strange:
4277220C mov r3, #0x93, 30
42772210 str
This is correct. When pc
is used for reading there is an 8-byte offset in ARM mode and 4-byte offset in Thumb mode.
From the ARM-ARM:
When an instruction reads the PC, the value read depends on which instruction set it comes from:
- For an ARM instruction, the value read is the address of the instruction plus 8 bytes. Bits [1:0] of this value are always zero, because ARM instructions are always word-aligned.
- For a Thumb instruction, the value read is the address of the instruction plus 4 bytes. Bit [0] of this value is always zero, because Thumb instructions are always halfword-aligned.
This way of reading the PC is primarily used for quick, position-independent addressing of nearby instructions and data, including position-independent branching within a program.
There are 2 reasons for pc-relative addressing.
mov r3, #0x12345678
is impossible to complete in 1 instruction, so the compiler may put this constant in the end of the function and use e.g. ldr r3, [pc, #0x50]
to load it instead.I don't know what mov r3, #0x93, 30
means. Probably it is mov r3, #0x93, rol 30
(which gives 0xC0000024
)?