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

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         ; 换行符

关键修改说明

  1. 拆分了输入缓冲区、输出缓冲区和数值运算变量,不再混用格式化字符串和存储变量。
  2. 新增ASCII与整数的双向转换逻辑,确保运算的是真实数值,输出的是正确的ASCII字符。
  3. 统一使用32位寄存器适配int 0x80系统调用,避免位数不兼容问题。
  4. 严格按照系统调用的参数要求传递长度、缓冲区地址等信息,保证读写操作正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:01:19