DOSBox环境下汇编语言阶乘计算程序异常求助
阶乘计算程序的错误排查与修正
你的汇编程序无法正确计算阶乘,核心是存在以下几个关键错误:
输入字符未转换为数值:
DOS中断int 21h的ah=1功能返回的是输入字符的ASCII码(例如输入'5'得到0x35),直接用该值进行乘法计算会得到错误结果。必须将其转换为十进制数值:mov ah, 1 int 21H sub al, '0' ; 将ASCII码转为十进制数值 mov bl, al ; 保存输入的数值到bl循环计数器未初始化:
loop指令依赖cx寄存器控制循环次数,但代码中未对cx赋值,导致循环次数随机(可能不执行或执行过多)。阶乘计算的循环次数应为输入值减1(例如输入5,需执行4次乘法:5×4、20×3、60×2、120×1),因此需要初始化cx:mov cx, bl ; cx设为输入的数值 dec cx ; 循环次数为输入值减1阶乘初始值与循环逻辑错误:
原代码中mul bl执行前未正确设置阶乘的初始值,且循环内未正确累积结果。正确的逻辑是将输入值作为阶乘的初始值(存在al),然后循环乘以递减的数值:mov al, bl ; al初始化为输入的数值(阶乘起始值) dec bl ; bl从输入值-1开始递减 fac: mul bl ; al = al * bl(阶乘累积) dec bl loop fac输出逻辑错误:
原代码输出的是递减后的bl值(最终为0),而非阶乘结果。需要将计算得到的数值(al中)转换回ASCII码才能正确显示,同时处理大于9的数值(120需要拆分为百位、十位、个位分别转换输出):; 将al中的数值转换为ASCII并输出(以120为例) mov cl, 100 div cl ; al=1(百位), ah=20 add al, '0' mov dl, al mov ah, 02h int 21h mov al, ah mov cl, 10 div cl ; al=2(十位), ah=0(个位) add al, '0' mov dl, al int 21h add ah, '0' mov dl, ah int 21h
修正后的完整代码
Title this program display the factorial of a number dosseg .model small .stack 0100H .data num db 10,13, 'Enter number: $' ans db 10,13, 'The factorial is $' .code ;clear screen mov ax, 03H int 10H mov ax, @data mov ds, ax lea dx,num mov ah, 09 int 21H ; 输入字符并转换为数值 mov ah, 1 int 21H sub al, '0' ; ASCII转十进制 mov bl, al ; 保存输入值 ; 初始化循环计数器 mov cx, bl dec cx ; 循环次数=输入值-1 jcxz output ; 如果输入0或1,直接输出 ; 初始化阶乘初始值 mov al, bl dec bl fac: mul bl ; al = al * bl dec bl loop fac output: lea dx,ans mov ah, 09 int 21H ; 将数值转换为ASCII并输出(处理0-255范围,因为al是8位) mov cl, 100 div cl add al, '0' mov dl, al mov ah, 02h int 21h mov al, ah mov cl, 10 div cl add al, '0' mov dl, al int 21h add ah, '0' mov dl, ah int 21h mov ah, 4ch int 21H end
说明
- 修正后的代码支持0-9的输入(因为8位寄存器最大存储255,9!是362880超过范围,若需更大数值需使用16位寄存器
ax存储结果)。 - 输入5时,程序会计算5! = 120并输出正确结果。
内容的提问来源于stack exchange,提问作者prestize
相关产品推荐
相关产品推荐

