【问题标题】:How to print register values in GDB?如何在 GDB 中打印寄存器值?
【发布时间】:2011-07-22 16:43:27
【问题描述】:

如何打印%eax%ebp 的值?

(gdb) p $eax
$1 = void

【问题讨论】:

  • 使用layout reg 让 gdb 显示所有整数和标志寄存器的表格,突出显示被上一条指令更改的那些。例如,请参阅stackoverflow.com/tags/x86/info

标签: gdb cpu-registers


【解决方案1】:

info registers 显示所有寄存器; info registers eax 仅显示寄存器 eax。命令可简写为i r

【讨论】:

  • 我得到:无效的寄存器 `%eax' 如果我只是做“信息寄存器”,eax 不会出现。然而,我正在 IDE 中查看我的代码程序集,其中使用指令生成了 EXC_BAD_ACCESS 信号:test %eax, %eax 这是在运行 gdb 的 XCode 中。为什么 gdb 不报告 eax 寄存器?
  • 同样的问题:%eax 在代码中,但是 print $eax 显示 void。
  • 布里奇特的回答对我有用。 geekosaur 的回答大多是正确的,但是你需要省略 % 符号,所以特定寄存器的命令是info registers eax。不过,我不确定这对于不同版本的 gdb 是否有所不同。
  • 我正在为 lldb 搜索相同的东西,所以让我注意一下:对于 lldb,命令是 register read [eax]
  • 如果您想在单步执行代码时连续显示寄存器值,您可以使用display。例如display $eax.
【解决方案2】:

如果您尝试在 GDB 中打印特定寄存器,则必须省略 % 符号。例如,

info registers eip

如果您的可执行文件是 64 位,则寄存器以 r 开头。以 e 开头是无效的。

info registers rip

这些可以缩写为:

i r rip

【讨论】:

    【解决方案3】:

    还有:

    info all-registers
    

    然后您可以获取您感兴趣的寄存器名称——对于查找特定于平台的寄存器非常有用(例如 ARM 上的 NEON Q...)。

    【讨论】:

    • 这讲的是关于我不知道存在的寄存器:-)
    • 在我的机器上,这会打印出eaxecx 和其他被info registers 隐藏的标准寄存器。这应该是公认的答案。
    【解决方案4】:
    • 如果只想检查一次,info registers 显示寄存器。
    • 如果只想看一个寄存器,例如display $esp continue display esp registers in gdb command line。
    • 如果要查看所有寄存器,layout regs 继续显示寄存器,使用 TUI 模式。

    【讨论】:

      【解决方案5】:

      Gdb 命令

      • i r <register_name>:打印单个寄存器,例如i r raxi r eax
      • i r <register_name_1> <register_name_2> ...:打印多个寄存器,例如i r rdi rsi
      • i r:打印除浮点和向量寄存器(xmm、ymm、zmm)以外的所有寄存器。
      • i r a:打印所有寄存器,包括浮点和向量寄存器(xmm、ymm、zmm)。
      • i r f:打印所有 FPU 浮动寄存器(st0-7 和其他一些 f*

      除了a (all) 和f (float) 之外的其他寄存器组可以通过以下方式找到:

      maint print reggroups
      

      如记录在:https://sourceware.org/gdb/current/onlinedocs/gdb/Registers.html#Registers

      提示

      • xmm0 ~ xmm15,是 128 位的,几乎每台现代机器都有它,它们是在 1999 年发布的。
      • ymm0~ymm15,是256位的,新机一般都有,2011年发布。
      • zmm0 ~ zmm31,是512位的,普通电脑可能没有(2016年),2013年发布,目前主要用于服务器。李>
      • xmm / ymm / zmm 只显示一个序列,因为它们在不同模式下是相同的寄存器。在我的机器上显示 ymm。

      【讨论】:

        【解决方案6】:

        p $eax 适用于 GDB 7.7.1

        从 GDB 7.7.1 开始,您尝试过的命令有效:

        set $eax = 0
        p $eax
        # $1 = 0
        set $eax = 1
        p $eax
        # $2 = 1
        

        此语法还可用于在不同的联合成员之间进行选择,例如对于可以是浮点数或整数的 ARM 浮点寄存器:

        p $s0.f
        p $s0.u
        

        来自the docs

        任何以“$”开头的名称都可以用作便利变量,除非它是预定义的特定于机器的寄存器名称之一。

        and:

        您可以在表达式中将机器寄存器内容引用为名称以“$”开头的变量。每台机器的寄存器名称不同;使用信息寄存器查看您机器上使用的名称。

        但到目前为止,我对控制寄存器的运气并不好:OSDev 2012 http://f.osdev.org/viewtopic.php?f=1&t=25968 || 2005 功能请求https://www.sourceware.org/ml/gdb/2005-03/msg00158.html || alt.lang.asm 2013 https://groups.google.com/forum/#!topic/alt.lang.asm/JC7YS3Wu31I

        ARM 浮点寄存器

        见:https://reverseengineering.stackexchange.com/questions/8992/floating-point-registers-on-arm/20623#20623

        【讨论】:

        • 能够在表达式中使用 $ 语法的寄存器真是太好了。
        【解决方案7】:

        对我来说最简单的是:

        (gdb) x/x $eax
        

        第一个x 代表ex胺,第二个x 是十六进制。您可以使用以下方式查看其他格式:

        (gdb) help x
        

        您可以使用x/s $eax 轻松打印字符串或使用x/a $ebp+4 返回地址。

        【讨论】:

        • x $eax 不显示eax 的内容。它显示地址为eax 的内容。
        • 当地址无法访问时你会得到一个错误——是的,它仍然显示来自“错误”的内容。所以我认为使用x 访问寄存器是不够的。这些命令有自己的用途。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-02
        • 2020-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-04
        • 1970-01-01
        相关资源
        最近更新 更多