我有一个用程序集编写的程序,它会因为分段错误而崩溃。 (代码无关紧要,但是here。)
我的问题是如何使用GDB调试汇编语言程序?
当我尝试在GDB中运行它并执行回溯时,我得不到有意义的信息。 (只是十六进制偏移。)
我该如何调试程序?
(我在Ubuntu上使用NASM,顺便说一下如果它有所帮助。)
答案 0 :(得分:2)
我只是将它直接加载到gdb
并逐步执行指令,随时监控所有寄存器和内存内容。
我确定我没有告诉你任何你不知道的事情,但这个程序似乎很简单,可以保证这种方法。我会为更复杂的代码留下花哨的调试技巧,比如回溯(甚至是断点)。
关于具体问题(代码转述如下):
extern printf
SECTION .data
format: db "%d",0
SECTION .bss
v_0: resb 4
SECTION .text
global main
main:
push 5
pop eax
mov [v_0], eax
mov eax, v_0
push eax
call printf
您似乎只是将5推到堆栈,然后是内存中的5的地址(v_0
)。如果你想调用printf
,我很确定你需要在某个时候推送格式字符串的地址。给予一个流氓格式字符串并不是一件好事。
可能是你的:
mov eax, v_0
应该是:
mov eax, format
并且我假设在调用printf
之后有更多代码你刚刚离开时不重要(否则你将永远不会降落返回)。
答案 1 :(得分:1)
在链接代码(使用gcc)时,您仍然可以使用Stabs标记进行汇编。
我建议使用YASM并使用-dstabs
选项进行汇总:
$ yasm -felf64 -mamd64 -dstabs file.asm
这就是我组装装配程序的方法。
NASM和YASM代码在很大程度上是可互换的(YASM有一些在NASM中不可用的扩展,但是每个NASM代码都与YASM很好地组合在一起)。
我使用gcc将我组装的目标文件链接在一起,或者在使用C或C ++代码进行编译时。使用gcc时,我使用-gstabs+
用调试标记编译它。