如何调试汇编?

How to debug assembly?

我有以下要调试的汇编文件test

我该怎么做?

请注意,我使用的是 x86-64 和 att 语法,而且我无权访问 C 代码。 我想在每一行之后停下来,并能够在 table 中看到寄存器(我记得有这样一个选项)。

我试过了:

gdb test
r

但我得到:

Starting program:  
No executable file specified.
Use the "file" or "exec-file" command.

在 运行ning GDB 之后在可执行文件上1:
使用startstarti分别在main或_start和运行程序中设置断点。

或使用 b 12 自己设置断点以在源代码第 12 行设置断点(如果您构建时有足够的调试信息使其工作),或 b *0x00401007 在地址上设置断点你 copy/pasted 从 disas 输出。

layout asm / layout reg 将 GDB 置于 text-UI 模式,在终端中使用“windows”进行反汇编和注册。 (这可能有点不稳定,您有时需要 control-L 来重绘屏幕,有时当您的进程退出时 GDB 会崩溃,尽管我不确定这是否专门来自 TUI。)
否则没有 TUI 模式,info regdisas 可能有用。

有关更多 asm 调试技巧,请参阅 https://whosebug.com/tags/x86/info 的底部。

特别是 strace ./test 对于查看程序进行的系统调用非常有用,解码为 C 风格。在您为自己的实验而玩的玩具程序中,这基本上可以作为检查错误 return 值的替代方法。


脚注 1:您没有正确执行该部分:

No executable file specified.

这意味着您 运行 gdb test.

所在的目录中不存在名为 test 的文件

你必须 assemble + link test.S 到一个名为 test 的可执行文件中,然后你才能 运行 GDB 在该文件上。如果 ls -l test 显示它,那么 gdb test 可以调试它。 (而且 ./test 可以 运行 它。)


通常 gcc -no-pie foo.S 是使调试更容易的好选择:地址将固定在 link 时间,因此 objdump -drwC -Mintel test 输出将匹配您在 [=81= 看到的地址]-时间。地址在数字上会更小,因此更容易直观地发现代码(.text)地址与 .rodata(现代 ld 将其放在单独的页面中,因此可以避免 exec 权限)与 .data / .bss.

无论哪种方式,堆栈地址仍然很容易从代码中区分出来,0x55​​5 ...或0x0000...XXXXXX在可执行文件中,0x7fffff...在堆栈中,mmap中的其他地址是运行驯化。 (但是 libc 也被映射到堆栈附近的高地址,有或没有 PIE。)

(或者如果你写的是 _start 而不是 maingcc -nostdlib -static foo.S 意味着 -no-pie