You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NASM调用syscall write时使用栈作为数据源无输出问题求助

问题成因分析

核心原因:混用了64位寄存器与32位系统调用接口

你遇到的问题本质是x86_64架构下32位兼容系统调用int 0x80的地址限制导致的,具体分两点:

  • int 0x80是32位Linux原生的系统调用接口,在64位运行环境下,内核只会处理低于0xFFFFFFFF的32位地址空间的指针参数,同时只会读取寄存器的低32位作为参数值。
  • x86_64 Linux的用户态栈默认映射到远高于0xFFFFFFFF的高地址区间,你将栈指针rsp赋值给rcx作为缓冲区地址传入时,int 0x80会直接截断rcx的高32位,得到的非法地址无法被内核访问,write系统调用执行失败,自然没有输出。
  • 你第一个示例能正常运行,是因为text标签指向的静态字符串位于低地址的代码段,截断低32位后地址仍然有效,所以没有触发问题。
修复方案

两种方案任选其一即可:

方案1:改用64位原生系统调用指令syscall

64位系统调用没有地址限制,参数寄存器约定和32位不同,对应修改后的代码如下:

global _start
section .text
_start:
  mov rcx, 0x0a47464544434241
  push rcx
  mov rsi, rsp    ; 64位write第2个参数:缓冲区地址存rsi
  mov rdx, 7      ; 第3个参数:输出长度
  mov rdi, 1      ; 第1个参数:stdout文件描述符1
  mov rax, 1      ; 64位write系统调用号为1
  syscall
  mov rax, 60     ; 64位exit系统调用号为60
  mov rdi, 0
  syscall

编译运行即可正常输出ABCDEFG。

方案2:编译为32位程序

如果你要保留int 0x80的写法,编译时指定32位目标格式即可,32位程序的栈地址落在32位地址空间范围内,不会被截断:

nasm -f elf32 your_code.asm -o test.o
ld -m elf_i386 test.o -o test

运行生成的32位可执行文件即可正常输出。

内容的提问来源于stack exchange,提问作者0ok3rn3lp4n1co0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:06:05