【问题标题】:"Segmentation fault" when trying to print an integer尝试打印整数时出现“分段错误”
【发布时间】:2020-04-04 08:12:08
【问题描述】:

我一直在尝试编写一个打印数字的汇编程序。 我编写了打印单个字符的程序printc

printc: push    ebp
        mov     ebp, esp

        mov     eax, 4
        mov     ebx, 1

        add     [ebp + 8], byte '0' 
        lea     ecx, [ebp + 8]

        mov     edx, 1

        int     0x80

        mov     esp, ebp
        pop     ebp

        ret

然后我尝试写printi所以:

printi: push    ebp
        mov     ebp, esp

        mov     eax, [ebp + 8]

        cmp     eax, 0
        je      end

        mov     ebx, 10
        div     ebx

        push    eax
        call    printi

        push    edx
        call    printc

end:    mov     esp, ebp
        pop     ebp

        ret

最后,我打电话给printi

_start: push    32 
        call    printi

得到了Segmentation fault (core dumped)。 知道为什么吗?

【问题讨论】:

  • 请在调试器中运行你的程序(谷歌如何使用gdb)并检查它在哪一行崩溃以及寄存器在那个时候有什么值。这应该会有很大帮助。
  • printi 返回后,您是否让执行从_start 的末尾滑落?如果它返回......这就是我们有调试器的原因,不要再浪费时间只查看段错误并找出 CPU 运行代码的确切方式。还可以使用strace ./a.out 来查看您是否成功进行了任何系统调用。顺便说一句,另请参阅 How do I print an integer in Assembly Level Programming without printf from the c library? 以了解更有效地执行此操作的非递归循环。
  • 另一个问题:您使用pushprintc 的参数放入堆栈,但您没有pop 或以其他方式丢弃这些堆栈槽。见NASM should I pop function argument after calling a function?

标签: linux assembly x86 segmentation-fault nasm


【解决方案1】:

正如 Peter Cordes 正确所说,如果由于 printi 中的无限递归,您的程序没有提前崩溃,那么您的程序将脱离 _start 并返回到未定义的代码。

存在无限递归的原因:您可能认为div ebxEAX 除以10。它没有:它将EDX:EAX 64 位值除以EBX,并且您无法控制@ 987654327@.

DIV 之前将EDX 归零允许程序打印一些东西(但不是所需的输出),然后在它掉下来printi 时崩溃。

【讨论】:

  • 另见我对这个问题的评论。
猜你喜欢
  • 1970-01-01
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
相关资源
最近更新 更多