7

我是组装新手。除了正在调试的实际代码之外,有没有办法在 GDB 中执行计算?例如,我正在使用 Linux IA-32 程序集(AT&T 语法)逐步执行以下操作:

   ;$esi is 0xbffff0a8 which refers to 1 after this command. $eax is 2
   0x08048cd5 <+42>:    lea    -0x20(%ebp),%esi

   ;$eax=ebx=2 after this instruction
   0x08048cd8 <+45>:    mov    %ebx,%eax 

   ;$eax equals 2 after this instruction               
   0x08048cda <+47>:    add    -0x4(%esi,%ebx,4),%eax

我只是没有看到 $eax 如何以 2 结束。我可以在 gdb 中发出如下指令:-0x4(%esi,%ebx,4) 并分析结果吗?

据我了解,$ebx 乘以 4 得到 8。将其添加到 $esi 得到 9。然后减去 -4 得到 5。然后将 5 添加到 $eax 中,即 2 得到 7。而不是 $ eax 为 2。

4

1 回答 1

7

如果您要求的话,您可以使用寄存器评估表达式。

gdbprint命令是你的朋友。

基本上你可以通过在前面加上一个美元符号来查询寄存器,例如

print $ecx

或在表达式中使用它们:

print $esi + $ebx + 4

您可以使用运算符取消引用内存*(如在 C 中):

print *$ecx

将打印指向的内存位置的内容ecx

虽然您不能直接输入汇编代码,但您可以将表达式转换为更高级的内容,如下所示:

print $eax - ($esi * $ebx)

此外,您可以使用强制转换为 C 数据类型转换为各种类型,例如

print (char)$ecx

会将 的内容打印ecx为字符。

print *(char**)$ecx

这将解释ecx为指向 的指针char*,然后您将其取消引用。因此,您会在ecx.

不过,这只是冰山一角。gdb是非常强大的工具。您可能还会发现该display命令很有用。它与 基本相同,只是它会在代码停止时print重复该命令(对断点有用)。您可以使用,或者如果您是自虐狂print来检查大多数寄存器。info registersinfo all-registers

您还可以使用以下方法更改寄存器的内容set

set $eax = 20

stepi通过指令,或continue运行程序。

PS 如果您不知道,您可能想学习如何设置断点等。

于 2012-10-08T01:29:40.800 回答