NASM x64 Linux:向数据段变量赋值后输出乱码求助
解决汇编代码中变量赋值后输出乱码的问题
核心错误分析
- 变量用途混淆:你把
.data段的valor同时当作格式化字符串和数值存储变量,dd "%d",4定义的是字符串常量,直接对其地址做减法并赋值,会破坏字符串结构,导致输出乱码。 - 系统调用位数不匹配:使用32位Linux系统调用
int 0x80时,不能混用64位寄存器(如rax、rbx),必须用32位寄存器(eax、ebx等)。 - 未做ASCII与整数的转换:
read系统调用读入的是ASCII字符(比如输入2,读入的是'2'即ASCII值50),直接做数值运算会得到错误结果,运算后也没转回ASCII就输出,自然显示乱码。
修正后的代码
section .text global main,_start main: mov ebp, esp _start: ; 读入ASCII形式的数字(最多3位) mov edx, 3 ; 读入3个字符(数字+换行) mov ecx, input_buf ; 存储到输入缓冲区 mov ebx, 0 ; 标准输入 mov eax, 3 ; read系统调用号 int 0x80 ; 输出原始输入 mov edx, eax ; 实际读入的字符数 mov ecx, input_buf mov ebx, 1 ; 标准输出 mov eax, 4 ; write系统调用号 int 0x80 ; 将ASCII转换为整数 mov eax, 0 mov ecx, input_buf ascii_to_int: mov bl, [ecx] cmp bl, 0xA ; 判断是否到换行符 je convert_done sub bl, 0x30 ; ASCII转数字('0'-'9'对应0-9) imul eax, 10 add eax, ebx inc ecx jmp ascii_to_int convert_done: ; 数值减1 sub eax, 1 ; 将整数转回ASCII mov ecx, output_buf + 2 ; 从缓冲区末尾开始填数字 mov ebx, 10 int_to_ascii: xor edx, edx div ebx add dl, 0x30 ; 数字转ASCII mov [ecx], dl dec ecx test eax, eax jnz int_to_ascii ; 输出减1后的结果(跳过前面的空字节) inc ecx mov edx, output_buf + 3 - ecx mov ebx, 1 mov eax, 4 int 0x80 ; 输出换行 mov edx, 1 mov ecx, newline mov ebx, 1 mov eax, 4 int 0x80 ; 退出程序 mov ebx, 0 mov eax, 1 int 0x80 section .data input_buf db 0, 0, 0, 0 ; 输入缓冲区 output_buf db 0, 0, 0, 0 ; 输出缓冲区 newline db 0xA ; 换行符
关键修改说明
- 拆分了输入缓冲区、输出缓冲区和数值运算变量,不再混用格式化字符串和存储变量。
- 新增ASCII与整数的双向转换逻辑,确保运算的是真实数值,输出的是正确的ASCII字符。
- 统一使用32位寄存器适配
int 0x80系统调用,避免位数不兼容问题。 - 严格按照系统调用的参数要求传递长度、缓冲区地址等信息,保证读写操作正确。
内容的提问来源于stack exchange,提问作者GreatField
相关产品推荐
相关产品推荐

