Я использую 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 может избежать общей проблемы переполнения регистра. Так что я не знаю, где улучшить мой код. У меня есть два предположения:
- Там что-то еще переполнено. Но я не могу его найти.
- Есть некоторые неизвестные ограничения с dosbox
Код ооочень длинный, я буду очень признателен, если кто-нибудь может дать мне какой-нибудь совет.