0

我正在使用 MASM 和 dosbox 来执行此操作,基本上将 C 版本转换为程序集。

int main()
{
    int a[20001];
    int temp,digit,n,i,j=0;
    scanf("%d",&n);
    a[0]=1;
    digit=1;
    for(i=2;i<=n;i++)
    {
        int num=0;
        for(j=0;j<digit;j++) 
        {
            temp=a[j]*i+num;
            a[j]=temp%10;
            num=temp/10;
        }
        while(num)
        {
            a[digit]=num%10;
            num=num/10;
            digit++;
        }
    }
    for(i=digit-1;i>=0;i--)
        printf("%d",a[i]);
    printf("\n");
    return 0;

我认为如果我遵循这条路线,寄存器溢出不会有问题。从 1 开始效果很好!到 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

;-----------------load input to n
    mov  bx, 0
    Newchar:
      mov  ah, 1
      int  21h 
      sub  al, 30h 
      jl  endinput
      cmp  al, 9    
      jg  endinput
      cbw  
      xchg   ax, bx
      mul   cx
      xchg  ax, bx    
      add   bx, ax 
      jmp   newchar 
    endinput:
    mov n,bl
;-----------------


    mov al,1
    mov array[0],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
      mov dh,0
      mov dl,0
      mov num,dl

      ; j = 0 = bx
      mov bx,0
      secondloop:
        ; temp=a[j]*i+num;
        mov al,i
        mov ah,array[bx]
        mul ah;->ax
        add ax,dx
        mov dh,10;borrow bh, then turn it back to 0
        div dh
        ; a[j]=temp%10;
        mov array[bx],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;borrow bh, then turn it back to 0
        div dh
        mov dh,0
        mov j,bl
        mov bh,0;bx was j, turn it to digit
        mov bl,digit
        mov array[bx],ah
        ; num=num/10;
        mov dl,al
        ; digit++;
        add bl,1
        mov digit,bl
        mov bl,j;turn bx back to j

        cmp dx,0
        jne whileloop

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




      ; reversely print the array
      mov bh,0
      mov bl,digit
      sub bl,1

    printloop:
      MOV  DL,array[bx]
      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

我认为C版本的算法可以避免寄存器溢出的常见问题。所以我不知道在哪里改进我的代码。我有两个猜测:

  1. 还是有东西溢出来。但我找不到它。
  2. dosbox 有一些未知的限制

代码很长,如果有人能给我一些建议,我将不胜感激。

4

0 回答 0