我是装配新手。除了正在调试的实际代码之外,有没有办法在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。
答案 0 :(得分:6)
您可以使用寄存器来评估表达式,如果这就是您所要求的。
gdb 的print
命令是你的朋友。
基本上,您可以通过在美元符号前加上查询寄存器,例如
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 registers
检查大多数寄存器,或info all-registers
。
您还可以使用set
:
set $eax = 20
和stepi
通过说明,或continue
运行程序。
P.S。如果你不知道,你可能想学习如何设置断点等。