I have a block of instructions for which I wanted to know how the pc register works. It says on Wikipedia, the pc register holds the value of the next instruction to be executed, however, looking at the disassembly graph of binary ninja for the same block of instructions it seems this is not entirely true.
Here is part of the disassembly graph by binary ninja, where in front of each memory load is written the address in memory from which the load happens.

000080ec ldr r3, [pc, #76] -> 0x813c = 0x80f0 + 0x4c -> pc = 80f0 ?? (shouldnt it be 80ee).
000080ee cmp r3, #0
000080f0 it eq
000080f2 ldreq r3, [pc, #68] -> 0x8138 = 0x80f4 + 0x44 -> pc = 80f4 (this makes sense).
000080f4 mov sp, r3
000080f6 sub.w sl, r3, #65536 (edited)
this also happens way down the code not always the pc holds the address of the next instruction to be executed.. is there something I should account for?
The key thing you are missing is that the value of
PCin the Thumbldr Rd, [Pc, #imm]instruction is aligned to 4 bytes before being used. The slightly abridged pseudo code from the ARMv7 Architecture Reference Manual is:So to come back to your example:
We know that
PCreads as the current address plus 4 bytes in Thumb mode, so PC reads as0x80f0. This value is already aligned to 4 bytes, sobasehas the same value. To this we add76(the immediate is always a multiple of four with the two least significant bits not stored) getting0x813c.For the second example:
This is the same instruction as the
ldrabove. The disassembler adds aneqsuffix to the mnemonic as the instruction is subject to conditional execution by the precedingITblock. This does not affect the instruction encoding in any way though.PCreads as0x80f6which is aligned to 4 bytes as0x80f4. To this we add68, obtaining0x8138as the address to load from.For further information, refer to the ARM Architecture Reference Manual.