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个字节的垃圾数据,这也会导致乱码。
快速解决思路
给你两个简单的修复方向:
- 替换回车为空字节:调用
accept后,rax寄存器里存的是实际读取的字节数,你可以把最后一个字节(也就是回车)替换成空字节:accept num1,5 mov byte [num1 + rax - 1], 0 ; 把回车替换成终止空字节 print num1, rax-1 ; 输出实际输入的数字长度,去掉回车 - 按实际读取长度输出:如果不想修改缓冲区内容,直接用
rax的值作为print的长度,但要注意减去回车的1个字节(如果用户确实按了回车的话),避免输出换行后的乱码。
内容的提问来源于stack exchange,提问作者asn
相关产品推荐
相关产品推荐

