c - 了解 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
- 这一行告诉我们什么:堆栈是否从内存地址开始
0x000000000040058c
,main+47
指的是什么?
解决方案
左列的内存地址是什么意思,为什么每条指令在下一个地址之间都是可变宽度的?
x86 机器代码指令是可变长度的。所以有些指令占用一个字节,而例如movabs $0x12345678abcdef, %rax
占用 10 个字节。硬限制是 15 个字节,但只有用冗余前缀有意填充才能一直到 15。
许多其他架构是 RISC 并且具有固定宽度的指令。
第二列是什么意思?
它告诉你符号的相对地址main
。请注意,内存中的实际位置不是在编译时分配的。
(编者注:这不是 PIE 可执行文件,因此绝对地址实际上是在链接时设置的。我们可以判断,因为地址0x00400...
位于地址空间的低 32 位,而不是0x55555555....
)
寄存器旁边的值是它的内存位置,还是注册表中包含的值?
寄存器不存储在内存中(罕见的架构除外);寄存器没有地址,是与内存分开的空间。它也没有显示恰好持有有效地址的寄存器所指向的值。
显示的值是电阻器本身的值。请注意rbx
和rcx
都显示0x0
.
这行告诉我们什么:堆栈是否从内存地址 0x000000000040058c 开始,main+47 指的是什么?
(编者注:这部分是错误的,但我不确定用其他东西替换它的确切含义。但 0x40058c 绝对不是 RSP 的合理值。 main+47
是内部某处的代码地址main
,就像 GDB 一样symbol+number
)。
这是堆栈的位置。您的代码很小,因此main
只占用少于 48 个地址的空间。请注意,内存通常以块的形式分配,因此堆栈不会出现在main+7
或紧跟在movl
指令后面的任何位置。
推荐阅读
- java - Maven 错误 Pom.xml - frontend-maven-plugin
- javascript - 将状态重置为初始值,而不是最近更新的状态
- python - 如何将列表的值与同一列表中的其他值进行比较?
- android - Android:如何在recyclerview中显示来自外部存储或厨房的视频列表
- reactjs - 反应本机文本输入中的 OnChangeText 未按预期工作
- reactjs - 为什么我的带有 Table 组件的 React 应用程序不显示所有记录?
- docker - 无法使用 hurley hyperledger fabric 安装链码
- python-3.x - 我怎样才能做出让我的机器人离开特定服务器的命令?
- docusignapi - DocuSign:必填复选框
- javascript - html: 显示本地化页面内容而不打开新页面或离开当前页面