首页 > 解决方案 > 了解 gdb 格式

问题描述

我正在尝试熟悉gdb并根据其格式和显示的内容提出一些问题:

─── Assembly ────
 0x00000000004004ed  main+0  push   %rbp
 0x00000000004004ee  main+1  mov    %rsp,%rbp
!0x00000000004004f1  main+4  movl   $0x539,-0x4(%rbp)

.

─── Registers ───────────────────────
rax 0x00000000004004ed         
rbx 0x0000000000000000      
rcx 0x0000000000000000

.

─── Stack ───────────────────
[0] from 0x000000000040058c in main+47 at main.c:7

标签: cdebuggingassemblygdbstack

解决方案


左列的内存地址是什么意思,为什么每条指令在下一个地址之间都是可变宽度的?

x86 机器代码指令是可变长度的。所以有些指令占用一个字节,而例如movabs $0x12345678abcdef, %rax占用 10 个字节。硬限制是 15 个字节,但只有用冗余前缀有意填充才能一直到 15。

许多其他架构是 RISC 并且具有固定宽度的指令。

第二列是什么意思?

它告诉你符号的相对地址main。请注意,内存中的实际位置不是在编译时分配的。

(编者注:这不是 PIE 可执行文件,因此绝对地址实际上在链接时设置的。我们可以判断,因为地址0x00400...位于地址空间的低 32 位,而不是0x55555555....

寄存器旁边的值是它的内存位置,还是注册表中包含的值?

寄存器不存储在内存中(罕见的架构除外);寄存器没有地址,是与内存分开的空间。它也没有显示恰好持有有效地址的寄存器所指向的值。

显示的值是电阻器本身的值。请注意rbxrcx都显示0x0.

这行告诉我们什么:堆栈是否从内存地址 0x000000000040058c 开始,main+47 指的是什么?

(编者注:这部分是错误的,但我不确定用其他东西替换它的确切含义。但 0x40058c 绝对不是 RSP 的合理值。 main+47是内部某处的代码地址main,就像 GDB 一样symbol+number)。

这是堆栈的位置。您的代码很小,因此main只占用少于 48 个地址的空间。请注意,内存通常以块的形式分配,因此堆栈不会出现在main+7或紧跟在movl指令后面的任何位置。


推荐阅读