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

x86_64 NASM汇编程序无法获取用户输入问题求助

问题根源:x86_64与32位Linux系统调用的寄存器约定差异

你猜的完全没错!问题的核心就是你混用了32位和64位Linux系统调用的寄存器规则,导致系统调用无法正确执行,所以程序看起来无输出直接终止。

关键差异说明

Linux下的32位x86和x86_64(amd64)架构,系统调用的触发方式和参数传递规则完全不同:

  • 32位模式:用int 0x80触发系统调用,参数依次存在eax(系统调用号)、ebx、ecx、edx这些32位寄存器中。
  • x86_64模式:标准方式是用syscall指令触发,参数依次存在rax(系统调用号)、rdi、rsi、rdx这些64位寄存器中。虽然x86_64也支持int 0x80调用32位系统调用,但会有寄存器截断、上下文切换的问题,很容易导致调用失败且无明显报错。

结合你的代码分析

你写的是x86_64汇编(针对64位系统),但全程用了32位的寄存器(eax、ebx、ecx)和int 0x80指令,系统调用无法正确识别你传递的参数(比如write调用需要的文件描述符、字符串地址、长度),所以实际执行时系统调用直接失败,但你没做错误检查,程序就直接走到exit调用退出了,看起来像是“无输出终止”。

当你把寄存器换成rax、rdi、rsi后,其实是切换到了x86_64的系统调用规则,系统能正确识别参数,所以程序正常运行。这里还要补充一句:最好把int 0x80换成syscall指令,这才是x86_64的标准系统调用触发方式,避免兼容问题。

修正后的代码示例(以_printMsg1为例)

_printMsg1:
    mov rax, 1          ; 64位sys_write的系统调用号(和32位一样是1,但寄存器不同)
    mov rdi, 1          ; 第1参数:stdout的文件描述符
    mov rsi, msg1       ; 第2参数:要输出的字符串地址
    mov rdx, len1       ; 第3参数:字符串长度
    syscall             ; 触发64位系统调用
    ret

额外提示

  • 64位Linux的系统调用号可以通过man syscalls查看,大部分和32位一致,但寄存器传递规则完全不同。
  • 写x86_64汇编时,尽量避免混用32位寄存器和int 0x80,保持代码风格统一,减少调试麻烦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:50:34