I have a small x86_64 assembly program and I don't see any register specifically called pc
(program counter?), though there is the instruction pointer, in the rip
register However, when I type in:
>>> p/x $rip
$15 = 0x4000c5
>>> p/x $pc
$16 = 0x4000c5
Both pc
and rip
have the same value. Is pc
an alias to rip
in gdb, or does it have another meaning?
It's GDB's generic name for the Program Counter / Instruction Pointer, whatever target ISA you happen to be debugging.
On x86-64, the architectural register name is RIP, so $pc
is an alias for $rip
. Note that this is the address of the next instruction to be executed, i.e. the one you're stopped on.
It's also the same address that RIP had while the previous instruction was executing (unless we got here via a branch): RIP-relative addressing is relative to the end of the current instruction (start of the next), same as relative branch displacements.
When execution is stopped in GDB, you can think of this state as being between instructions. The previous instruction is fully finished, but RIP is still pointing at the instruction that's yet to be decoded + executed. (So $pc
is actually the exception-return address from the debug exception or single-step TF trap.)
On ARM, the instruction-pointer register is called PC or R15, so there it happens that $pc
actually matches one of the names used in ARM manuals.
I don't know if ARM GDB's $pc
or $r15
actually reflects the fact that reading the R15 register with mov r0, r15
gives you the address of 2 instructions later, not the next instruction like x86-64 lea rax, [rip + 0]
.