NASM汇编代码放入手动构建ELF运行触发段错误,求排查方法
问题分析与解决
你碰到的机器码带0x66前缀、运行触发段错误的问题,核心是NASM默认汇编模式和你手动构建的ELF架构不匹配。
为什么会出现0x66前缀?
0x66是x86架构的操作数大小前缀,用于切换指令的操作数位数。你看到的66 B8 00 00 00 00,是NASM默认生成了16位模式下的指令(比如mov ax, 0),但你手动构建的ELF是32位或64位执行环境,指令位数不兼容,直接导致段错误。
解决方法:指定正确的汇编参数
根据你手动构建的ELF是32位还是64位,给NASM添加对应参数:
若构建的是32位ELF
用-f elf32指定32位ELF目标文件,或直接生成纯二进制机器码时加-m32:
# 生成32位ELF目标文件 nasm test.asm -f elf32 -o asm.o # 直接生成32位纯二进制机器码 nasm test.asm -f bin -m32 -o asm.bin
此时mov eax,1会被编码为B8 01 00 00 00,和教程中的手动汇编结果一致。
若构建的是64位ELF
注意:64位系统的syscall调用规则和32位不同——exit的调用号是60(而非32位的1),退出码需存在rdi寄存器(而非ebx)。先修改汇编代码:
mov rax,60 mov rdi,4 syscall
再用-f elf64或-m64编译:
# 生成64位ELF目标文件 nasm test.asm -f elf64 -o asm.o # 直接生成64位纯二进制机器码 nasm test.asm -f bin -m64 -o asm.bin
验证机器码是否正确
编译完成后可通过工具检查指令编码:
# 查看ELF目标文件的指令 objdump -d -M intel asm.o # 查看32位纯二进制文件的指令 ndisasm -b 32 asm.bin # 查看64位纯二进制文件的指令 ndisasm -b 64 asm.bin
内容的提问来源于stack exchange,提问作者AGL
相关产品推荐
相关产品推荐

