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

时间:2011-04-05 01:57:22

标签: c assembly debugging

我正在尝试了解此代码中发生的情况,特别是在__asm__内。如何单步执行汇编代码,以便我可以打印每个变量而不是什么?

具体来说,我试图通过这个来弄清8()的含义是什么,看看它是如何知道它在索引2处进入数组的。

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

3 个答案:

答案 0 :(得分:5)

stepi命令一次遍历程序集一条指令。还有nexti用于单步执行函数调用。这些命令不符合'只有命令的唯一前缀的类型就足够了'适用于大多数命令的规则 - 部分原因是nextstep命令完全是这些命令的前缀和部分是因为这些不经常使用,而且当它们通常被知道他们真正想要使用它们的人使用时。

info registers显示了很多寄存器内容。

您还希望使用disassemble命令查看反汇编。

help命令提供了有关所有这些命令的更多信息,例如:

(gdb) help info registers

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

(gdb) info registers rax
rax            0x0  0

raxeax的x86_64版本) 第一列是寄存器名称,第二列是十六进制值,第三列是整数值。

help命令也有用disassemble

请记住,gdb对许多命令都有标签完成,这不仅可以用于简单的命令,但很多时候它会为你提供不好的建议 - 但它有时会有所帮助。

在内联汇编中包含一个标签,可以让您在开头轻松创建一个断点。

答案 1 :(得分:3)

我从来没有擅长AT& T语法,但我很确定8(%eax)部分意味着“地址存储在EAX中的地址后8个字节”,也就是说,它是相对于存储在寄存器中的地址。

英特尔语法中的近似等价物将是这样的(在我的头顶,所以这里完全有可能存在一些小错误......)

mov eax, a
mov DWORD PTR [eax+8], 99

答案 2 :(得分:1)

movl $_a, %eax      // load the memory address of a into %eax

movl $99, 8(%eax)   // jump 8 bytes and store number 99 (which is a[2])

在我看来,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])
相关问题