.s文件程序退出码异常,手动调用exit触发段错误求助
x86-64汇编退出码异常与mov指令段错误排查
一、退出码为14的原因及修复
如果你的程序是通过write系统调用打印字符串,write执行后会将写入的字节数返回至%rax寄存器。若程序没有显式调用退出函数/系统调用,进程结束时会默认把%rax中的值作为退出码返回给系统。"Hello, world!\n"刚好是14字节,所以write返回14,最终退出码就是14。
修复方式:打印完成后显式触发退出流程:
- 用系统调用直接退出(x86-64 Linux):
.section .text _start: # 此处是write打印代码 mov $0, %rdi # 设置退出码为0 mov $60, %rax # 指定exit系统调用号 syscall - 若基于libc编译(用gcc链接),在
main函数末尾设置返回值后返回:mov $0, %eax ret
二、mov指令触发段错误的核心原因及修复
段错误的本质是执行了非法内存操作,你的情况大概率是以下几种问题:
1. 立即数语法错误(最常见)
AT&T汇编语法中,立即数必须加$前缀。如果你写的是mov 0, %rdi,汇编器会把0解析为内存地址,试图从地址0读取数据写入%rdi——而地址0属于无效内存,直接触发段错误。
正确写法:
mov $0, %rdi # 64位赋值 # 或32位赋值(x86-64会自动零扩展到%rdi) movl $0, %edi
2. 代码放置在非可执行段
如果你的mov指令写在了.data或.rodata段(这些段默认是不可执行的),当程序执行到该区域时,会因内存权限不足触发段错误。
修复:确保所有执行代码都放在.text段,开头必须声明:
.section .text .global _start # 或.global main,取决于链接方式 _start: # 你的代码逻辑
3. 程序入口设置错误
如果用gcc链接程序,入口点必须是main;如果直接用ld链接,入口点必须是_start。若入口指向了数据区域,执行到数据时会触发非法指令错误。
内容的提问来源于stack exchange,提问作者Basil
相关产品推荐
相关产品推荐

