C 如何使用GDB调试器查看asm内容?

C 如何使用GDB调试器查看asm内容?,c,assembly,debugging,C,Assembly,Debugging,我试图理解这段代码中发生了什么,特别是在\uuu asm\uu中。如何逐步完成汇编代码,以便打印每个变量以及其他变量 具体地说,我试图一步一步地了解8() /* a[2] = 99 in assembly */ __asm__("\n\ movl $_a, %eax\n\ movl $99, 8(%eax)\n\ "); 我从来都不擅长at&T语法,但我很确定8(%eax)部分的意思是“存储在eax中的地址后的地址8字节”,也就是说,它是相对于存储在寄存器中的地址的偏

我试图理解这段代码中发生了什么,特别是在
\uuu asm\uu
中。如何逐步完成汇编代码,以便打印每个变量以及其他变量

具体地说,我试图一步一步地了解
8()

 /* a[2] = 99 in assembly */
  __asm__("\n\
     movl $_a, %eax\n\
     movl $99, 8(%eax)\n\
");

我从来都不擅长at&T语法,但我很确定
8(%eax)
部分的意思是“存储在eax中的地址后的地址8字节”,也就是说,它是相对于存储在寄存器中的地址的偏移量

英特尔语法中的近似等价物是这样的(我想不起来,所以这里完全可能有一些小错误…)

在我看来,
a
是一个int数组(int在大多数平台上有4个字节)。因此,通过增加4个字节,您将访问数组的下一项。为该数组赋值的其他示例包括:

movl $10, (%eax)   // store number 10 on the the first position: a[0]

movl $20, 4(%eax)  // jump 4 bytes from the address loaded in %eax 
                   // and store number 20 on the next position (a[1])

stepi
命令一次执行一条指令。还有一个用于跳过函数调用的
nexti
。这些命令不符合适用于大多数命令的“仅键入命令的唯一前缀就足够了”规则——部分原因是
next
step
命令完全是这些命令的前缀,部分原因是这些命令使用得不太频繁,并且通常由知道他们真的想使用它们

info registers
显示大量寄存器内容

您还需要使用
反汇编
命令查看反汇编

有关所有这些命令的更多信息,可通过
help
命令获得,例如:

(gdb) help info registers
告诉您,
info registers
显示整数寄存器及其内容,但它也告诉您,如果您提供寄存器名称,它会将输出限制为该寄存器的值:

(gdb) info registers rax
rax            0x0  0
rax
eax
的x86_64版本) 第一列是寄存器名,第二列是十六进制值,第三列是整数值

对于
反汇编
命令也有有用的
帮助

请记住,gdb对许多命令都有制表符补全功能,这不仅仅适用于简单的命令,尽管很多时候它会给您提供一些不好的建议,但有时还是有帮助的


在内联程序集中包含一个标签将允许您轻松地在开始时创建断点。

它实际上应该是
mov DWORD PTR[eax+8],99
我相信,但是是的。@caf:是的,你完全正确。这就是我在早上4点回答问题时得到的答案……在gdb中,你需要的关键字是
反汇编
。。。)作为将来的参考,我如何计算数组元素中有多少字节?如果是一根绳子呢?如果我在另一个系统上呢?等我猜我得看一下文档,但在互联网上这类东西似乎真的很难找到。你必须阅读:从头开始编程。这是一本免费的网络书籍,非常棒:我原以为
ni
也会通过
\uuu asm\uuuu
,所以我在
\uu asm\uuu
行设置了一个断点,然后键入
ni
,它通过了所有程序集。我做错什么了吗?当你说“逐步通过所有”时,你的意思是每个装配说明都是单步走吗?我以为那就是你想要的。
(gdb) help info registers
(gdb) info registers rax
rax            0x0  0