【问题标题】:Segmentation error upon calling scanf in x86_64 AT&T在 x86_64 AT&T 中调用 scanf 时出现分段错误
【发布时间】:2016-09-29 10:32:19
【问题描述】:

我对 Assembly 很陌生,我正在尝试创建一个使用 scanf 从用户那里接收数字的程序。然后它输出“结果:(数字)” 运行代码时,我不断收到分段错误。 这是我现在得到的代码:

.global main
mystring: .asciz"input\n"
formatstring: .asciz" %d"
resultstring: .asciz "Result: %ld\n"

main:
    movq    $0, %rax    
    movq    $mystring, %rdi
    call    printf
    call    inout
    movq    $0, %rax
    movq    $resultstring, %rdi
    call    printf
    jmp end

inout:
    pushq   %rbp
    subq    $8, %rsp
    leaq    -8(%rbp), %rsi
    movq    $formatstring, %rdi
    movq    $0, %rax
    call    scanf
    popq    %rbp    
    ret


end:
    movq    $0, %rdi
    call    exit

我怀疑“inout”方法有问题。有什么解决方案可以让这个程序正常工作吗?

【问题讨论】:

  • inout 中,您没有设置rbp,仅将旧值压入堆栈,然后您访问rbp-8 内存(访问发生在scanf 内部),它可能指向任何地方。顺便说一句,“我不断收到分段错误”表明您缺乏努力,通过调试,您应该能够判断它在哪条指令处出现段错误,以及 CPU 的状态是什么(寄存器值、代码地址、堆栈内容).. . 但那时你不需要问 SO,因为你可能会自己看到 scanf%rsi 参数是假的。
  • 而且你不会在 scanf 调用后恢复rsp,使用错误的rsp 值执行pop %rbp。此外,您应该确保rsp 在调用scanf 时对齐。检查这个:cs.lmu.edu/~ray/notes/gasexamples(看起来足够短,也许完整,4秒快速查看)
  • 可以在此处找到一些关于似乎类似问题的 cmets:stackoverflow.com/questions/39679848/…
  • 一次推送和一次sub rsp, 8 也会使堆栈错位。 ABI 要求它在运行 CALL 之前是 16B 对齐的(这会推送 8B 返回地址)。

标签: linux assembly x86-64 att


【解决方案1】:
leaq    -8(%rbp), %rsi

在此指令中,您指的是%rbp 寄存器,但您忘记实际初始化它!

【讨论】:

    猜你喜欢
    • 2016-08-07
    • 2015-01-09
    • 2020-10-26
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    相关资源
    最近更新 更多