我是装配新手.除了正在调试的实际代码之外,有没有办法在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
Run Code Online (Sandbox Code Playgroud)
我只是没有看到$ eax如何结束2.我可以在gdb中发出如下指令:-0x4(%esi,%ebx,4)并分析结果吗?
根据我的理解,$ ebx乘以4得到8.然后将$ esi加到9.然后减去-4得到5.然后将5加到$ eax,这是2得到7.而不是$ eax是2.
您可以使用寄存器来评估表达式,如果这就是您所要求的.
gdb的print命令是你的朋友.
基本上你可以通过在美元符号前加上查询寄存器,例如
print $ecx
Run Code Online (Sandbox Code Playgroud)
或者在表达式中使用它们:
print $esi + $ebx + 4
Run Code Online (Sandbox Code Playgroud)
您可以使用*运算符取消引用内存(如C中所示):
print *$ecx
Run Code Online (Sandbox Code Playgroud)
将打印指向的内存位置的内容ecx.
虽然您无法直接键入汇编代码,但您可以将表达式转换为更高级别的内容,如下所示:
print $eax - ($esi * $ebx)
Run Code Online (Sandbox Code Playgroud)
此外,您可以使用强制转换为C数据类型转换为各种类型,例如
print (char)$ecx
Run Code Online (Sandbox Code Playgroud)
会打印出ecx作为角色的内容.
print *(char**)$ecx
Run Code Online (Sandbox Code Playgroud)
它会被解释ecx为指针char*,然后你将其解除引用.所以你会在包含的地址中看到字符串的内容ecx.
这只是冰山一角.gdb是非常强大的工具.您可能还会发现该display命令很有用.它基本上是相同的print,除了它会print在代码停止时重复命令(对断点很有用).你可以使用info registers或者info all-registers如果你是受虐狂来检查大多数寄存器.
您还可以使用set以下命令更改寄存器的内容:
set $eax = 20
Run Code Online (Sandbox Code Playgroud)
并stepi通过说明或continue运行程序.
PS如果你不知道,你可能想学习如何设置断点等.