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

64位NASM汇编无法获取用户输入数字,输出乱码原因解析

汇编输入存储后终端输出乱码的原因分析

嘿,我来帮你拆解下这个输出乱码的问题——我之前写x86_64 Linux汇编时也踩过几乎一模一样的坑!先把你的代码片段贴出来方便分析:

%macro print 2
    mov rax,1
    mov rdi,1
    mov rsi,%1
    mov rdx,%2
    syscall
%endmacro
%macro accept 2
    mov rax,0
    mov rdi,0
    mov rsi,%1
    mov rdx,%2
    syscall
%endmacro
%macro exit 0
    mov rax,60
    mov rdi,0
    syscall
%endmacro
section .bss
num1 resb 5 ;1 extra for enter key
choice resb 2
tempbuff resb 8

接下来咱们逐个分析导致乱码的核心原因:

  • 输入缓冲区缺少终止空字节:Linux的read系统调用(你accept宏里用的rax=0)只会把用户输入的字节(包括按下回车的0x0A)写入缓冲区,不会自动在末尾添加空字节\0。而你用的print宏调用的write系统调用(rax=1)会从缓冲区开始,连续输出你指定长度的字节——如果没有空字节,它会一直输出到内存中第一个0的位置,这就会把num1后面的choice、tempbuff里的随机初始值也打印出来,自然就是乱码了。

  • 回车字符干扰+固定长度输出的问题:你注释里说num1留了1个字节给回车,这意味着用户输入数字后按回车,accept会把回车也读进num1。如果调用print时你传的长度是5(缓冲区总大小),哪怕用户只输入了2位数字,write也会输出这2位数字、回车,再加上缓冲区里剩下3个字节的垃圾数据,这也会导致乱码。

快速解决思路

给你两个简单的修复方向:

  1. 替换回车为空字节:调用accept后,rax寄存器里存的是实际读取的字节数,你可以把最后一个字节(也就是回车)替换成空字节:
    accept num1,5
    mov byte [num1 + rax - 1], 0 ; 把回车替换成终止空字节
    print num1, rax-1 ; 输出实际输入的数字长度,去掉回车
    
  2. 按实际读取长度输出:如果不想修改缓冲区内容,直接用rax的值作为print的长度,但要注意减去回车的1个字节(如果用户确实按了回车的话),避免输出换行后的乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:12:12