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

NASM汇编乘除运算中ASCII与整数转换输出异常问题求助

加减'0'的底层原理

ASCII编码中,数字字符'0'到'9'的编码值是连续的,对应十进制范围为48~57。因此转换逻辑非常固定:

  • 从输入读取到的数字是ASCII字符形式,要转成可运算的整数,直接对字符值执行sub '0'即可得到对应的十进制数值
  • 运算完成后的整数结果要输出为可见字符,对结果执行add '0'即可转成对应的ASCII数字字符
你代码中的核心错误

你的转换逻辑思路是对的,但是放置位置和寄存器操作存在多处错误:

  1. 多余的sub ax, '0'操作:你已经对num1、num2执行了转整数操作,乘法得到的结果已经是整数,你在mul bx之后又做了一次sub ax, '0',直接把2*3=6的结果变成了6-48=-42,后续运算完全错误。
  2. 除法前未清零DX寄存器:16位乘法mul bx的结果是32位,存在DX:AX寄存器组中;16位除法div cx默认用DX:AX除以CX,你没有清零DX,寄存器里的垃圾值会导致除法结果完全异常。
  3. 读取输入时取到多余的换行符:你每次读取2字节,其中第一字节是输入的数字,第二字节是换行符,你直接用mov ax, [num1]把包含换行符的两个字节都读进AX,高8位的换行符会干扰数值计算,应该只取低8位的数字字符。
  4. 第一次sys_write调用参数不全:你第一次调用sys_write的时候没有设置ecx(输出缓冲区地址)和edx(输出长度),属于无效调用。
修正后的完整代码
segment .bss
    num1 resb 2
    num2 resb 2
    num3 resb 2
    res  resb 1

section .text
    global _start

_start:
    ; 读取num1
    mov eax, 3
    mov ebx, 0
    mov ecx, num1
    mov edx, 2
    int 0x80

    ; 读取num2
    mov eax, 3
    mov ebx, 0
    mov ecx, num2
    mov edx, 2
    int 0x80

    ; 读取num3
    mov eax, 3
    mov ebx, 0
    mov ecx, num3
    mov edx, 2
    int 0x80

    ; 转换num1为整数,存入al
    mov al, [num1]
    sub al, '0'
    ; 转换num2为整数,存入bl
    mov bl, [num2]
    sub bl, '0'
    ; 乘法 al*bl,结果存入ax
    mul bl
    ; 转换num3为整数,存入cl
    mov cl, [num3]
    sub cl, '0'
    ; 除法前清零dx
    xor dx, dx
    div cl
    ; 结果转ASCII
    add al, '0'
    mov [res], al

    ; 输出结果
    mov ecx, res
    mov edx, 1
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; 退出
    mov eax, 1
    int 0x80

修正后输入2 3 2即可得到正确输出3。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:42:03