64位环境下nasm编写的write系统调用无法正常工作该如何解决?
问题原因与解决方法
核心问题
你编写的汇编代码虽然编译为64位ELF格式,但使用了x86_32体系下的系统调用触发方式int 0x80。Linux内核处理int 0x80中断时,默认走32位兼容系统调用逻辑,调用的是32位系统调用表,所以你填写64位的write调用号1不会生效,反而填写32位write调用号4才能正常运行。
64位x86 Linux原生系统调用规则
x86_64体系下Linux有专门的系统调用触发方式和参数传递规则,和32位完全不同:
- 触发系统调用使用
syscall指令,而非int 0x80 - 系统调用号存储在
rax寄存器中 - 参数按顺序传递到
rdi、rsi、rdx、r10、r8、r9寄存器,而非32位的ebx、ecx、edx等寄存器
修正后的64位hello_world代码
segment .text ; 代码段 global _start ; 链接器需要的入口声明 _start: ; 程序入口点 mov rdx, len ; 第三个参数:字符串长度 mov rsi, msg ; 第二个参数:字符串缓冲区地址 mov rdi, 1 ; 第一个参数:stdout文件描述符 mov rax, 1 ; 64位write系统调用号 syscall ; 触发系统调用 mov rax, 60 ; 64位exit系统调用号 mov rdi, 0 ; 退出状态码0 syscall ; 触发系统调用 section .data msg db "Hello, World", 0xa len equ $ - msg
编译和链接命令保持不变,运行后即可正常输出内容。
内容的提问来源于stack exchange,提问作者Visrut
相关产品推荐
相关产品推荐

