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

如何在TASM中实现通用数值转字符串转换器?现有代码仅支持0-9

修正TASM数值转字符串转换器(支持大于9的数值)

问题根源分析

你的转换器无法处理大于9的数值,核心问题有两个:

  1. 存储数值的变量类型错误:real_first_number定义为db(字节型),只能存储0-255的数值,超过就会溢出,导致后续转换出错。
  2. 字符串转数值时的操作宽度不匹配:原代码用字节寄存器(al、bl、bh)进行乘法和加法,无法处理多位数的累加结果,同样会引发溢出。

关键修正点

1. 调整数值存储变量类型

将real_first_number和digit_saver从db改为dw,支持0-65535的数值范围:

real_first_number dw 0
digit_saver dw 1

2. 修正字符串转数值的逻辑

把字节操作改为字操作,确保累加和乘法不会溢出:

  • 使用ax、bx等字寄存器代替字节寄存器
  • 用movzx将字节值零扩展为字,避免高位垃圾值干扰计算
  • 每次处理完一位后,将10的幂次除以10,适配下一位的权重

3. 修正数值转字符串的入口加载

在convert_counter_to_asc开始时,将完整的字数值加载到ax,而不是只加载低字节:

mov ax, [real_first_number]  ; 代替原来的mov al, [real_first_number]

完整修正后的程序

assume cs: code, ds: data, ss: stck
code segment
begin:
    mov ax, data
    mov ds, ax

    ; 缓冲输入
    mov ah, 0ah
    mov dx, offset first_input
    int 21h

    ; 标记输入字符串结束
    mov bx, 0
    mov bl, [first_input + 1]
    mov first_input[bx + 2], '$'
    
    ; 换行
    mov ah, 02h
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h

    ; 统计输入字符总数(含控制字节)
    mov di, 0
count_characters:
    mov al, first_input[di]
    cmp al, '$'
    je end_count
    inc di
    jmp count_characters

end_count:
    mov cx, di
    sub cx, 2  ; 减去前两个控制字节,得到数字字符个数

; ====================== 数字字符个数转字符串输出 ======================
    mov si, offset counter_buffer 
    push cx

convert_counter_to_ascii:
    mov dx, 0
    mov ax, cx
    mov bx, 10
    div bx
    add dl, '0'
    dec si
    mov [si], dl
    mov cx, ax
    cmp cx, 0 
    jnz convert_counter_to_ascii

    mov ah, 09h
    mov dx, si
    int 21h

    ; 换行
    mov ah, 02h
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h

    pop cx

    ; 计算最高位的10的幂次
    sub cx, 1
    push cx
    
    cmp cx, 0
    je just_one_digit
    
pow_loop:
    mov ax, [digit_saver]
    mov bx, 10
    mul bx
    mov [digit_saver], ax
    loop pow_loop

    pop cx
    add cx, 1  ; 恢复数字字符个数
    push cx

    mov di, cx
    mov si, 2

; ====================== 字符串转数值 ======================
convert_string_to_number:
    mov al, first_input[si]
    cmp si, di
    je just_one_digit
    inc si
    sub al, '0'
    movzx ax, al  ; 字节转字,避免高位垃圾值
    mov bx, [digit_saver]
    mul bx
    add [real_first_number], ax
    ; 更新10的幂次(除以10,为下一位准备)
    mov ax, [digit_saver]
    mov bx, 10
    div bx
    mov [digit_saver], ax
    loop convert_string_to_number
 
just_one_digit:
    mov si, cx
    add si, 2
    mov al, first_input[si]
    sub al, '0'
    movzx ax, al
    add [real_first_number], ax

; ====================== 数值转字符串输出 ======================
    mov si, offset first_number_buffer
    mov ax, [real_first_number]  ; 加载完整的字数值

convert_counter_to_asc:
    mov dx, 0
    mov bx, 10
    div bx
    add dl, '0'
    dec si
    mov [si], dl
    mov cx, ax
    cmp cx, 0 
    jnz convert_counter_to_asc

    mov ah, 09h
    mov dx, si
    int 21h

    mov ax, 4C00h
    int 21h
code ends

data segment
    first_input db 10, ?, 10 dup (?)
    real_first_number dw 0  ; 改为字类型,支持更大数值
    first_number_buffer db 6 dup ('$')
    counter_buffer db 6 dup('$')
    digit_saver dw 1  ; 同步改为字类型
data ends

stck segment stack
    db 256 dup(?)
stck ends

end begin

额外说明

  • 修正后的程序支持0-65535范围内的数值转换,涵盖了大部分常用的小整数场景
  • movzx指令用于将字节值零扩展为字,避免高位出现随机垃圾值导致计算错误
  • 字符串转数值时,每次处理完一位后将10的幂次除以10,适配下一位的权重(比如从100→10→1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 22:38:15