x86_64汇编中Segmentation Fault问题:系统调用故障排查
为什么第二段x86-64汇编代码会触发Segmentation Fault?
两段代码的核心差异在于字符串数据在.text段中的位置,以及程序执行流程是否会走到这些数据上:
运行正常的代码(第一段)
global _start section .text _start: mov rdi,1 mov rsi,hello_world mov rdx,13 mov rax,1 syscall ; exit(result) mov rax,60 mov rdi,0 syscall hello_world: db "Hello World!",10
这段代码的执行流程是:
- 调用
write系统调用打印字符串 - 紧接着调用
exit系统调用终止程序
hello_world的字符串数据放在exit系统调用之后,程序执行到exit就直接退出了,永远不会走到数据所在的内存位置,所以不会有问题。
触发错误的代码(第二段)
global _start section .text _start: mov rdi,1 mov rsi,hello_world mov rdx,13 mov rax,1 syscall hello_world: db "Hello World!",10 ; exit(result) mov rax,60 mov rdi,0 syscall
这段代码的执行流程出了问题:
- 调用
write系统调用打印字符串后,CPU会继续执行后续的内存指令 - 接下来的内存内容是
hello_world的字符串字节("Hello World!\n"对应的ASCII值),这些字节不是合法的x86-64机器指令 - CPU尝试将这些数据解码为指令执行时,会触发非法操作(比如尝试访问无效内存、执行未定义指令),最终引发Segmentation Fault——程序根本没机会执行到后面的
exit系统调用。
关键原因
.text段是可执行代码段,操作系统会把这个段标记为可执行,但里面的内容必须是合法的机器指令。你把字符串数据放在了代码的执行路径上,当CPU执行到这里时,会把数据当作指令处理,自然会出错。
正确的做法是把字符串数据放到.data(可写数据段)或.rodata(只读数据段)中,避免和执行代码混在一起。
内容的提问来源于stack exchange,提问作者codesmith
相关产品推荐
相关产品推荐

