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
相关产品推荐
相关产品推荐

