如何调试汇编程序?

时间:2010-09-09 03:54:50

标签: debugging gdb segmentation-fault nasm

我有一个用程序集编写的程序,它会因为分段错误而崩溃。 (代码无关紧要,但是here。)

我的问题是如何使用GDB调试汇编语言程序?

当我尝试在GDB中运行它并执行回溯时,我得不到有意义的信息。 (只是十六进制偏移。)

我该如何调试程序?

(我在Ubuntu上使用NASM,顺便说一下如果它有所帮助。)

2 个答案:

答案 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+用调试标记编译它。