GDB info registers命令-输出的第二列

GDB info registers命令-输出的第二列,gdb,cpu-registers,Gdb,Cpu Registers,在gdb中运行info registers时,我们得到一个类似于以下内容的输出: rax 0x1c 28 rbx 0x0 0 rcx 0x400a60 4196960 rdx 0x7fffffffde88 140737488346760 rsi 0x1 1 rdi 0x400932 4196658 rbp 0x0 0x0 rsp

在gdb中运行
info registers
时,我们得到一个类似于以下内容的输出:

rax            0x1c 28
rbx            0x0  0
rcx            0x400a60 4196960
rdx            0x7fffffffde88   140737488346760
rsi            0x1  1
rdi            0x400932 4196658
rbp            0x0  0x0
rsp            0x7fffffffde68   0x7fffffffde68
r8             0x400ad0 4197072
r9             0x7ffff7dea560   140737351951712
r10            0x7fffffffdc30   140737488346160
r11            0x7ffff7732dd0   140737344908752
r12            0x4007f0 4196336
r13            0x7fffffffde80   140737488346752
r14            0x0  0
r15            0x0  0
rip            0x7ffff7732dd0   0x7ffff7732dd0
eflags         0x202    [ IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0
虽然我确实理解
rax
rcx
等的格式,但GDB正在将第二列的值转换为十进制,这似乎并不一致。一些寄存器,即
rsp
rip
以十六进制显示相同的值,即使在第二列中也是如此<另一方面,code>eflags在第二列中显示标志


gdb
这样做的原因是什么?如果它要显示相同的信息(在
rsp
rip
的情况下),它不是多余的吗?另外,这如何推广到其他体系结构上?(以上输出用于x86-64)。

info registers命令以原始格式(十六进制)和自然格式打印寄存器

自然格式基于寄存器的类型,在gdb源代码的xml文件中声明。例如,包含:

<reg name="rax" bitsize="64" type="int64"/>
<reg name="rbx" bitsize="64" type="int64"/>
<reg name="rcx" bitsize="64" type="int64"/>
<reg name="rdx" bitsize="64" type="int64"/>
<reg name="rsi" bitsize="64" type="int64"/>
<reg name="rdi" bitsize="64" type="int64"/>
<reg name="rbp" bitsize="64" type="data_ptr"/>
<reg name="rsp" bitsize="64" type="data_ptr"/>
<reg name="r8" bitsize="64" type="int64"/>
<reg name="r9" bitsize="64" type="int64"/>
<reg name="r10" bitsize="64" type="int64"/>
<reg name="r11" bitsize="64" type="int64"/>
<reg name="r12" bitsize="64" type="int64"/>
<reg name="r13" bitsize="64" type="int64"/>
<reg name="r14" bitsize="64" type="int64"/>
<reg name="r15" bitsize="64" type="int64"/>

<reg name="rip" bitsize="64" type="code_ptr"/>
<reg name="eflags" bitsize="32" type="i386_eflags"/>
<reg name="cs" bitsize="32" type="int32"/>
<reg name="ss" bitsize="32" type="int32"/>
<reg name="ds" bitsize="32" type="int32"/>
<reg name="es" bitsize="32" type="int32"/>
<reg name="fs" bitsize="32" type="int32"/>
<reg name="gs" bitsize="32" type="int32"/>

您可以看到,带有
type=“int64”
type=“int32”
的寄存器在其自然输出中显示为十进制值,因为它们通常是通用寄存器,可用于引用内存和赋值

而带有
type=“data\u ptr”
type=“code\u ptr”
的寄存器具有其自然格式的十六进制值,因为它们通常用于引用内存地址

对于带有
type=“i386\u eflags”
的寄存器,输出设置为“真”的标志,因为对于该寄存器,对于人类来说,知道哪个标志设置为“真”而不是十六进制值更有意义

对于其他体系结构,这取决于寄存器类型在其源代码中的定义方式。您可以查看的源代码,以及


编辑:

资料来源:@MarkPlotnick answer at和@perror answer at


抱歉,我忘了提到源代码。

事实上,在汇编中,您只能找到三种类型的值:

  • 数值
  • 存储器地址
  • 说明(操作码)
  • 通用寄存器,如
    rax
    rbx
    ,…,用于存储数值(将触发程序行为)或内存地址(以知道读/写或跳转的位置)

    当然,由于大多数人习惯于在程序中使用十进制格式的值,所以当寄存器可能包含此类值时,显示十进制格式很重要

    现在,重要的是要知道内存地址通常是以十六进制格式给出的(主要是出于紧凑性的原因)。而且,通用寄存器也可能包含内存地址。这就是为什么
    gdb
    同时显示十进制和十六进制格式,以防其中一种格式最适合当前值

    寄存器
    rsp
    rip
    (和
    rbp
    )是特殊情况,因为它们专门用于存储地址(仅此),因此将此类寄存器的内容转换为十进制格式是没有用的。这就是为什么
    gdb
    只给出这些寄存器的十六进制格式

    最后,
    rflags
    /
    eflags
    的情况有点特殊,因为该寄存器的含义是逐位依赖的(参见下图)


    因此,给出十进制、十六进制或二进制格式对用户来说并不是真正有用的(除非您可以立即将数字与标志关联起来)。但是,给出设置为“true”的标志列表更有用(这是您在示例中看到的
    [IF]
    )。然而,
    gdb
    给出了
    eflags
    的十六进制值,因为它可以被访问并用作程序中的值(我看到这一点是为了混淆)。

    我称之为剽窃。。。当你问这个问题时,你抄袭了我大部分的答案,但没有正确引用你的来源。。。我强烈反对这种做法@我在那边提到了这个问题。此外,我已经更改了我的答案,删除了你答案中的部分。