如何调试汇编的程序?

发布于 2024-09-18 08:10:31 字数 269 浏览 5 评论 0原文

我有一个用汇编语言编写的程序,该程序因分段错误而崩溃。 (代码无关紧要,但在此处。)

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

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

如何调试程序?

(我在 Ubuntu 上使用 NASM,顺便说一句,如果这有帮助的话。)

I have a program written in assembly that crashes with a segmentation fault. (The code is irrelevant, but is here.)

My question is how to debug an assembly language program with GDB?

When I try running it in GDB and perform a backtrace, I get no meaningful information. (Just hex offsets.)

How can I debug the program?

(I'm using NASM on Ubuntu, by the way if that somehow helps.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蹲在坟头点根烟 2024-09-25 08:10:31

我将其直接加载到 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之后还有更多代码,您只是将其视为不重要(否则您将继续当它返回时,将永远不会着陆)。

I would just load it directly into gdb and step through it instruction by instruction, monitoring all registers and memory contents as you go.

I'm sure I'm not telling you anything you don't know there but the program seems simple enough to warrant this sort of approach. I would leave fancy debugging tricks like backtracking (and even breakpoints) for more complex code.

As to the specific problem (code paraphrased below):

        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

You appear to be just pushing 5 on to the stack followed by the address of that 5 in memory (v_0). I'm pretty certain you're going to need to push the address of the format string at some point if you want to call printf. It's not going to take to kindly to being given a rogue format string.

It's likely that your:

mov eax, v_0

should be:

mov eax, format

and I'm assuming that there's more code after that call to printf that you just left off as unimportant (otherwise you'll be going off to never-never land when it returns).

说好的呢 2024-09-25 08:10:31

当链接代码(使用 gcc)时,您应该仍然能够使用 Stabs 标记进行汇编。

我建议使用 YASM 并使用 -dstabs 选项进行组装

$ yasm -felf64 -mamd64 -dstabs file.asm

:这就是我组装汇编程序的方式。

NASM 和 YASM 代码在大多数情况下是可以互换的(YASM 有一些 NASM 中不可用的扩展,但每个 NASM 代码都可以与 YASM 很好地组装)。

我使用 gcc 将组装的目标文件链接在一起,或者在使用 C 或 C++ 代码进行编译时使用。使用 gcc 时,我使用 -gstabs+ 使用调试标记来编译它。

You should still be able to assemble with Stabs markers when linking code (with gcc).

I reccomend using YASM and assembling with -dstabs options:

$ yasm -felf64 -mamd64 -dstabs file.asm

This is how I assemble my assembly programs.

NASM and YASM code is interchangable for the most part (YASM has some extensions that aren't available in NASM, but every NASM code is well assembled with YASM).

I use gcc to link my assembled object files together or while compiling with C or C++ code. When using gcc, I use -gstabs+ to compile it with debug markers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文