DarrenTitor 发表于 2020-4-30 15:23:14

求大数阶乘,思路应该没错,但是求15以上的阶乘时会卡住

.MODEL SMALL,STDCALL
.386
   

.DATA
digit db 0
n   db ?
i   db 0
j   db 0
num   db 0
array db 10000 dup(0)


   
.CODE
main proc
    ;装载数据段地址
    mov ax,@data
    mov ds,ax

;-----------------把输入存到n中
    movbx, 0
    Newchar:
      movah, 1
      int21h
      subal, 30h
      jlendinput
      cmpal, 9   
      jgendinput
      cbw
      xchg   ax, bx
      mul   cx
      xchgax, bx   
      add   bx, ax
      jmp   newchar
    endinput:
    mov n,bl
;-----------------


    mov al,1
    mov array,al

    mov al,1
    mov digit,al

    mov ch,0
    mov cl,n
    sub cl,2
    firstloop:
      ;i = n - cx = al
      mov ah,0
      mov al,n
      sub ax,cx
      mov i,al
      ;num = 0 = dl,dh也用了
      mov dh,0
      mov dl,0
      mov num,dl

      ;------------ j = 0 = bx
      mov bx,0
      secondloop:
      ; --------temp=a*i+num;
      mov al,i
      mov ah,array
      mul ah;->ax
      add ax,dx
      mov dh,10;暂时借用dh,一会儿要再改回dh=0
      div dh
      ; ----------a=temp%10;
      mov array,ah
      ; -----------num=temp/10;
      mov dl,al
      mov num,dl
      mov dh,0

      add bx,1
      mov j,bl
      cmp bl,digit
      jl secondloop

      whileloop:
      mov dl,num
      mov dh,0
      cmp dx,0
      je tonext
      mov ax,dx
      mov dh,10;暂时借用dh,一会儿要再改回dh=0
      div dh
      mov dh,0
      mov j,bl
      mov bh,0;原本bx是j,暂时改成digit
      mov bl,digit
      mov array,ah
      ; num=num/10;
      mov dl,al
      ; digit++;
      add bl,1
      mov digit,bl
      mov bl,j;还原bx的值j

      cmp dx,0
      jne whileloop

      tonext:
      mov al,i
      add al,1
      mov i,al
      sub cx,1
      cmp al,n
      jle firstloop




      ; ------------逆序打印一下
      mov bh,0
      mov bl,digit
      sub bl,1
      
    printloop:
      MOVDL,array
      add dl,30h
      mov ah,2
      int 21h
      sub bx,1
      cmp bx,0
      jnl printloop

      jmp exit;

    exit:
      mov ah,4ch
      int 21h
    main endp
    end main
原文链接:https://blog.csdn.net/lisp1995/article/details/52403507

编译用的是MASM,我基本是完全照搬上边这篇文章的思路,只是c语言改写成汇编
(应该有些地方不用把寄存器数据写回到数据段,我这里为了跑通写的繁琐了,之后还可以简化)


问题:
求14以下结果输出正确,但是算15阶乘就会卡住
推测一,有些变量用db存储,会溢出,但是digit在算15!时应该只比10多一点,其他变量就更小了
推测二,来自dosbox的未知限制?这个不确定,我再debug试试

既然能算出14!,按照链接中这个思路应该更大的也可以算,虽然代码有点长,各位能提出建议我会很感谢的

wp231957 发表于 2020-4-30 15:33:57

超范围了啊
更换算法

DarrenTitor 发表于 2020-4-30 15:38:23

wp231957 发表于 2020-4-30 15:33
超范围了啊
更换算法

这个算法就是为了解决超范围的问题吧(?

wp231957 发表于 2020-4-30 15:43:28

DarrenTitor 发表于 2020-4-30 15:38
这个算法就是为了解决超范围的问题吧(?

你这代码16位的?,不都是eax   ebx   ecx   edx
64位的,没玩过,不知道是啥

发表于 2020-5-26 08:48:07

超过位数了,就使用多个寄存器或者多个内存单元分别存放数的高位和低位,目前没有必要做这种题目,理解循环指令的工作流程即可。
页: [1]
查看完整版本: 求大数阶乘,思路应该没错,但是求15以上的阶乘时会卡住