我有一个小的x86_64汇编程序,我没有看到任何名为pc
(程序计数器)的寄存器,尽管有指令指针,在rip
寄存器中。然而,当我输入以下内容时:
>>> p/x $rip
$15 = 0x4000c5
>>> p/x $pc
$16 = 0x4000c5
pc
和 rip
的值相同。在 gdb 中,pc
是 rip
的别名吗?还是它有其他的含义?
我有一个小的x86_64汇编程序,我没有看到任何名为pc
(程序计数器)的寄存器,尽管有指令指针,在rip
寄存器中。然而,当我输入以下内容时:
>>> p/x $rip
$15 = 0x4000c5
>>> p/x $pc
$16 = 0x4000c5
pc
和 rip
的值相同。在 gdb 中,pc
是 rip
的别名吗?还是它有其他的含义?
在GDB中,$pc是指程序计数器/指令指针的通用名称,无论您正在调试的目标ISA是什么。
在x86-64上,体系结构寄存器名称为RIP,因此$ pc是$ rip的别名。请注意,这是要执行的下一条指令的地址,即您停止的指令。
这也是RIP在执行前一个指令时拥有的相同地址(除非我们通过分支到达这里):RIP相对寻址相对于当前指令的结尾(下一条指令的开头),与相对分支位移相同。
当在GDB中停止执行时,您可以将此状态视为“处于”指令之间。上一条指令已经完成,但是RIP仍然指向尚未解码+执行的指令。(因此,$ pc实际上是从调试异常或单步TF陷阱返回的异常返回地址。)
在ARM上,指令指针寄存器称为PC或R15,因此在那里,$ pc
实际上与ARM手册中使用的名称之一匹配。
我不知道ARM GDB的$ pc
或$ r15
是否反映了读取带有mov r0,r15
的R15寄存器实际上会给您提供两个指令后的地址,而不是像x86-64 lea rax,[rip + 0]
一样是下一个指令。
$ pc
和/或$ r15
,获取两个指令地址的方式,而不是下一个要执行的指令。 在x86-64上,RIP位于两个指令之间,与执行先前指令(如果它不是分支)期间相同。 但ARM不是这样的。 我猜GDB希望轻松访问停止处的地址/将要执行的指令。 - Peter Cordes