如何调试在命中_start之前产生段错误的NASM程序集

时间:2017-11-17 18:39:55

标签: assembly gdb nasm

我正在编写以下令人讨厌的(NASM)代码,将鼠标指针设置为位置100,100:

section .text
    global _start:

_start:
    mov eax, 4
    mov ecx, 100
    mov edx, 100
    int 33h

    mov eax, 1
    int 0x80

我使用以下make文件编译它:

DEPS = Mouse.asm

Mouse: $(DEPS)
    nasm -f elf $(DEPS)
    ld -m elf_i386 -s -o Mouse Mouse.o

然后我使用$ sudo gdb Mouse在GDB中打开它。然后我输入“break _start”并按“r”运行。当我这样做时,我得到以下输出:
“启动程序:/ home / tyler / ASM / Mouse / Mouse

编程接收信号SIGSEGV,分段故障。 0x0804806f在? () “

在我看来,它甚至都没有在_start打破断点,所以我不知道我做错了什么。我该如何调试呢?

1 个答案:

答案 0 :(得分:2)

为了回答您提出的问题(而不是您实际遇到的问题),请使用@ Ped7g建议"滥用" GDB的错误处理是为了让它在第一条指令之前停止而不知道正确的地址:

  • b *0在地址零处设置断点(这是不可能的)。
  • r运行程序,此时GDB尝试实际设置断点。它失败,在执行任何指令之前停止
  • d 1删除无效断点
  • si(或stepi)将从此处单步执行。

这是调试没有符号的程序的有用技巧,即使它是使用ASLR(gcc -pie)动态链接的,因此您无法获得真正的ELF入口点地址使用readelf -a

你做了什么:

  

然后我输入" break _start"并按" r"跑。

当我使用您使用的相同命令构建后,我得到

Reading symbols from ./Mouse...(no debugging symbols found)...done.
(gdb) b _start
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (_start) pending.

我必须输入yn才能输入r来运行程序。

所以我在asm源中标记为_start:的指令实际上没有断点。我只有一个挂起断点,如果我给GDB一个符号表,它将被设置在某处。 (可以将调试符号剥离到一个单独的文件中,因此这种gdb行为是有道理的。但不幸的是,在这种情况下你很困惑。:/)

您的二进制文件已被删除,因为您使用ld -s构建了二进制文件。这与您想要调试的内容相反。使用nasm -g -Fdwarf使用现代dwarf调试信息格式代替STABS,以获得更好的符号信息。

(gdb) r
Starting program: /home/peter/src/SO/Mouse

Program received signal SIGSEGV, Segmentation fault.
0x0804806f in ?? ()

0x0804806f处的说明是您的int 33h

_start之前它没有分段,它只是没有停止,因为你从来没有实际设置一个断点。在静态链接的二进制文件中,在用户空间中运行的第一条指令是ELF入口点处的指令。 (在动态链接的二进制文件中,ELF解释器首先运行并最终跳转到您的_start或任何您称为入口点的位置。)

使用layout reg显示寄存器和反汇编。使用set disassembly-flavor intel获取GNU的类似MASM的语法,当你知道它应该是什么时,该语法足够接近NASM。将它们放在~/.gdbinit中。另请参阅代码wiki的底部,了解有关gdbstrace的更多调试提示。

正如评论者指出的那样,你的程序无法在Linux下本地运行。 Linux本身不支持BIOS int 33h ABI,只支持自己的系统调用ABI。 What are the calling conventions for UNIX & Linux system calls on i386 and x86-64。这就是int 33h段错误的原因。

如果你想编写MS-DOS或PC-BIOS代码,请使用像BOCHS这样的仿真器(它有一个内置调试器,可以让你单步执行任何操作,甚至是引导程序)。