64位NASM汇编代码在WSL中运行出现Segmentation fault求助
问题分析与解决
你的代码出现段错误和调试断点失败的核心原因是:你编写的是32位Linux系统调用代码,但编译成了64位ELF程序,64位Linux的系统调用规范和32位完全不同,直接混用会导致寄存器参数传递错误、内核调用异常,进而触发段错误。
解决方案一:修改为64位系统调用代码
64位Linux使用syscall指令而非int 80h,系统调用号、寄存器使用规则也不同。修改后的代码如下:
section .data msg: db "Hello world!", 0x0a errmsg: db "Error!", 0x0a section .bss buf1: resb 40 buf2: resb 20 section .text global _start write_msg: mov rax, 1 ; 64位write系统调用号为1 mov rdi, 1 ; 标准输出(stdout)的文件描述符 mov rsi, msg ; 待写入的缓冲区地址 mov rdx, 13 ; 写入的字节数 syscall ; 触发内核调用 ret _start: call write_msg mov rax, 60 ; 64位exit系统调用号为60 mov rdi, 0 ; 退出码0 syscall
编译执行命令保持不变:
nasm -g -f elf64 helloworld.asm ld -m elf_x86_64 -static -o helloworld helloworld.o ./helloworld
调试时直接设置断点到write_msg即可,无需手动加偏移:
gdb helloworld set disassembly-flavor intel break write_msg run
解决方案二:编译为32位程序(保留原代码)
如果想继续使用32位int 80h调用的代码,需要编译成32位ELF程序,步骤如下:
- 先安装WSL的32位支持库:
sudo apt update && sudo apt install gcc-multilib libc6-i386
- 修改编译命令为32位目标格式:
nasm -g -f elf32 helloworld.asm ld -m elf_i386 -static -o helloworld helloworld.o ./helloworld
此时调试断点设置也能正常工作,直接用break write_msg即可。
内容的提问来源于stack exchange,提问作者FarbKlexx
相关产品推荐
相关产品推荐

