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

TASM汇编求数字各位和代码出现除零错误,求助错误定位与解析

理解除零错误并修复你的TASM代码

首先,咱们先搞清楚除零错误是什么:当CPU尝试执行除数为0的除法指令时,会触发#DE(除法错误)中断——这是因为数学上除以0没有定义,CPU会直接终止程序并抛出这个错误。

接下来看你的代码里导致错误(以及潜在问题)的地方:

1. 伪指令语法错误(最可能触发除零的原因)

你把多个汇编伪指令挤在了同一行:dosseg .model small .stack .data。TASM要求每个伪指令单独占一行,这种写法会让汇编器无法正确解析程序的内存模型、段布局,可能引发各种意外问题——比如寄存器被错误初始化(比如BX变成0),导致后续div bx触发除零错误。

正确的写法应该拆分:

dosseg
.model small
.stack 100h  ; 可选指定栈大小,增强程序稳定性
.data

2. 除法前未清零DX寄存器(潜在错误)

执行div bx(16位无符号除法)时,被除数是DX:AX组合(DX是高16位,AX是低16位)。你的代码第一次进入cifra循环时,DX还是之前调用int 21h后的残留值(比如offset nr),虽然不会直接触发除零,但会导致除法结果错误。

你需要在进入除法循环前先清零DX:

xor si,si
xor dx,dx  ; 先清零DX,确保被除数是0:AX(仅AX存着各位和)
cifra:
    mov bx,0ah
    div bx
    add dl,30h
    mov rezultat[si],dl
    inc si
    xor dx,dx  ; 下次除法前再次清零DX
    cmp ax,0
    jne cifra

3. 字符转数字的顺序优化(非错误,但更合理)

你现在的代码是先加ASCII码再减30h:add al,nr[si] → sub al,30h。虽然数学上等价于先转数字再加,但如果各位和超过255会导致AL溢出(比如多个大数相加),更清晰的写法是先把字符转换成数字再累加:

urmatorul_caracter:
    inc si
    mov bl, nr[si]
    sub bl, 30h  ; 先转成数字0-9
    add al, bl   ; 再累加到结果
    cmp si,cx
    jne urmatorul_caracter

4. 结果缓冲区定义冗余

rezultat DB 10,10 dup(?)的第一个字节是为DOS 0Ah功能调用设计的缓冲区长度,但你只是用它来存储转换后的ASCII字符,不需要这个字节,改成rezultat DB 10 dup(?)更合适。


修复后的完整代码

dosseg
.model small
.stack 100h
.data
    nr          DB 10,10 dup(?)
    rezultat    DB 10 dup(?)
    mesaj       db 13,10,'Introduceti numarul:$'
    mesaj_suma  db 13,10,'Suma cifrelor numarului este: $'
.code
pstart:
    mov ax,@data
    mov ds,ax

    ; Afiseaza mesajul de introducere
    mov ah,09
    mov dx,offset mesaj
    int 21h

    ; Citeste numarul de la tastatura
    mov ah,0ah
    mov dx,offset nr
    int 21h

    ; Prepara contorul pentru cifre
    mov si,1
    mov cl,nr[si]
    and cx,00FFh
    inc cx  ; CX = numarul de cifre + 1 (pozitia finala)

    ; Initializeaza rezultatul cu 0
    xor ax,ax

urmatorul_caracter:
    inc si
    ; Converteste caracterul la numar si aduna la suma
    mov bl, nr[si]
    sub bl, 30h
    add al, bl
    cmp si,cx
    jne urmatorul_caracter

    ; Converteste suma la sir de caractere
    xor si,si
    xor dx,dx  ; Reseteaza DX pentru impartire
cifra:
    mov bx,0ah
    div bx
    add dl,30h
    mov rezultat[si],dl
    inc si
    xor dx,dx
    cmp ax,0
    jne cifra

    ; Afiseaza mesajul rezultatului
    mov ah,9
    mov dx,offset mesaj_suma
    int 21h

    ; Afiseaza rezultatul inversat
caracter:
    dec si
    mov ah,02
    mov dl,rezultat[si]
    int 21h
    cmp si,0
    jne caracter

    ; Termina programul
    mov ah,4ch
    int 21h
END pstart

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:43