You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux汇编程序出现Segmentation fault (core dumped)问题求助

你的AT&T汇编代码段错误原因及修复方案

嘿,我来帮你排查这个段错误的问题!你的代码核心问题是对puts函数的用法理解有误,咱们一步步拆解:

错误原因分析

  • puts的参数要求错误:puts函数的第一个参数(放在%rdi寄存器)需要是以空字符结尾的字符串的内存地址,但你直接把字符'3'的ASCII值(0x33)放到了%rdi里。CPU会把这个数值当作内存地址去访问,而0x33这个地址属于未分配的内存区域,自然会触发段错误。
  • 代码格式不规范:.text和.globl main应该分开写在不同行,虽然部分汇编器可能容忍,但这是容易引发问题的不规范写法。

修复方案

方案1:用puts打印字符串形式的数字

如果你坚持使用puts,需要先定义一个包含目标数字和空终止符的字符串,再把它的内存地址传给%rdi:

.text
.globl main
main:
    # 定义存储数字的字符串(放在.data段更符合规范)
    .section .data
digit_str:
    .asciz "3"  # .asciz指令会自动添加空终止符
    .section .text

    movq $digit_str, %rdi  # 将字符串的内存地址传入%rdi
    call puts

    movq $0, %rax  # main函数返回0表示正常退出
    ret

方案2:用write系统调用直接打印单个字符(更贴合需求)

如果只是打印单个数字,使用Linux系统调用write会更直接,不需要依赖C标准库的puts:

.text
.globl main
main:
    # write系统调用参数说明:
    # rax=1(系统调用编号),rdi=1(标准输出文件描述符)
    # rsi=要打印字符的地址,rdx=打印的字节长度
    movq $1, %rax           # 传入write的系统调用号
    movq $1, %rdi           # 指定输出到标准输出
    movq $digit_char, %rsi  # 传入存储数字字符的地址
    movq $1, %rdx           # 打印1个字节
    syscall

    movq $0, %rax           # main函数返回0
    ret

.section .data
digit_char:
    .byte 0x33  # 存储'3'的ASCII码值

你也可以用更精简的写法,直接把字符放到栈上(不用额外的.data段):

.text
.globl main
main:
    subq $1, %rsp           # 在栈上分配1字节的临时空间
    movb $0x33, (%rsp)      # 把'3'的ASCII码存入栈中

    movq $1, %rax
    movq $1, %rdi
    movq %rsp, %rsi
    movq $1, %rdx
    syscall

    addq $1, %rsp           # 恢复栈的初始状态
    movq $0, %rax
    ret

这样就能正确打印出数字'3'啦!

内容的提问来源于stack exchange,提问作者Soleil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:47:05