【问题标题】:Segmentation fault on push inside a function x86_64 GAS在函数 x86_64 GAS 内推送时出现分段错误
【发布时间】:2018-11-13 22:28:52
【问题描述】:

我有一个小程序,它只是将一个项目添加到堆栈中,然后输入一个函数来添加另一个项目。问题是每次执行时它都有一个奇怪的行为。

函数如下:

.section .data

.section .text

.globl _start
_start:
    # Push
    push $1
    # Function call
    call pfun
    movq $60, %rax
    syscall

.type pfun, @function
pfun:
    # Push
    push $2
    # Return
    ret

一点也不复杂,但是会出现分段错误,如果你尝试调试它,你会发现当程序进入函数内部时会发生错误,但它不会有任何关于它所在位置的信息。

程序收到信号SIGSEGV,分段错误。 0x0000000000000002 在?? ()

现在,如果您在函数 push 后添加“pop”并运行它,那么它将成功构建并运行。但是如果你调试它,你会发现它永远不会使用“n”(下一个)命令进入函数内部。

我已经搜索了答案,但没有发现任何与 ASM 类似的东西。最近开始学习 ASM,对我来说它看起来非常好,所以真的不知道为什么会这样。

【问题讨论】:

  • 如果您查阅指令集参考,您将看到ret 弹出堆栈顶部并将其用作返回地址。由于您推送值2,它会尝试去那里,但这是一个无效的地址。您可以看到打印在错误中。您应该在尝试返回之前平衡堆栈。请注意,n 命令专门设计为不单步执行函数调用。使用ssi 命令。请参阅 gdb 中的 help
  • 感谢@Jester 我现在看到的帮助。如果您愿意,可以将其发布为答案。

标签: assembly gdb segmentation-fault gnu-assembler


【解决方案1】:

你的问题在这里:

pfun:
    push $2
    ret

我认为你没有正确理解call/ret。您的功能等同于jmp 2,并且总是在下午触发异常。 callpush (r)eip and then jmp 相同,retpop (r)eip 相同。在通话/功能中,您需要 pop 您在此处推送的所有内容或 add (r)esp,0x??

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    相关资源
    最近更新 更多