【问题标题】:Call printf produces segmentation fault, core dumped error in assembly compiled with gcc [duplicate]调用 printf 在使用 gcc 编译的程序集中产生分段错误、核心转储错误 [重复]
【发布时间】:2020-09-03 18:19:13
【问题描述】:

我从不认为是时候在这里问我的第一个问题了,但我来了。

作为我大学学习的一部分,我必须学习装配,而在互联网上搜索并没有找到我的问题的答案。 问题是当我尝试这个简单的代码时,我得到了段错误核心转储:

.text                        

hello_str:                    
    .asciz "Hello, world!\n"                      

.global  main                      
main:
    
    movq %rsp, %rbp     
    movq $0, %rax
    movq hello_str, %rdi

    call printf

 

我使用 gcc -no-pie -o hello.o hello.s 然后 ./hello.o 评论调用 printf 使其运行,但没有输出(显然)。 问题是我做错了什么? 我的电脑在 64 位上运行,安装的是 Windows 10 操作系统,但我使用适用于 Linux 的 Windows 子系统来编译程序。

【问题讨论】:

  • 即使使用 $hello_str 也会出现同样的错误
  • 可能是堆栈对齐或调用约定问题...
  • 确保第一个参数需要在 rdi 中传递,并检查这个答案:stackoverflow.com/questions/12678230/how-to-print-argv0-in-nasm/…
  • 是的,确实如此。我发现了问题,我也会把它作为答案。我需要在开头输入: pushq %rbp
  • movq hello_str, %rdi 是一个 qword 负载。也许您的意思是movq $hello_str, %rdi 传递地址? (或者更好,lea hello_str(%rip), %rdi)。对齐堆栈不足以使此代码正常工作。另外,如果没有ret 在通话后,这显然会崩溃。

标签: assembly gcc segmentation-fault


【解决方案1】:

所以我找到了答案。问题是我需要在这一切之前提出: pushq %rbp 并将 hello_str 修改为 $hello_str

我不知道它的确切作用,但它似乎在那里工作。

【讨论】:

  • Macmade 提到这可能是由于堆栈对齐。对main 的调用使rsp 指向超过16 字节边界的8 个字节。 ABI 要求您将 rsp 更改 8 以再次对齐它,然后再拨打另一个电话。尽管无论如何也可能需要保存和恢复rbp(调用main的代码可能需要这个)。
猜你喜欢
  • 1970-01-01
  • 2021-06-30
  • 2020-09-08
  • 1970-01-01
  • 2023-04-11
  • 2019-03-14
  • 1970-01-01
  • 2019-01-14
  • 2017-11-10
相关资源
最近更新 更多