0

Displaying a factorial number using assembly language and DOSBox.

The result of my code is:

Enter number: 5
The factorial is 5

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
    mov bl,al

    sub bl,1

    fac:
    mul bl    ;al = al*bl
    sub bl,1
    
    loop fac

    lea dx,ans
    mov ah, 09
    int 21H

    mov ah, 02
    mov dl, bl
    int 21H

    mov ah, 4ch
    int 21H
    int 20H

end
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
prestize
  • 13
  • 2
  • 1
    How does it not work? What did the debugger tell you? Anyway, check what the `loop` instruction does. Also you don't do any text<->number conversion which is required before and after the calculation. – Jester Jan 31 '23 at 14:48

1 Answers1

0

Calculating 5! produces 120, so in order to display the result you can't just use the single character ouput function 02h from DOS. Read Displaying numbers with DOS to learn how to display multi-digit numbers.

 mov ah, 1
 int 21H
 mov bl,al
 sub bl,1
fac:
 mul bl    ;al = al*bl
 sub bl,1
 loop fac
  • When you respond with 5 to the DOS.Getcharacter function 01h, you will receive the ASCII code for this digit which is 53. Before you can start using the digit in your calculation, you need to convert it. For decimal digits it requires a mere subtraction by 48: sub al, 48 which you can also write as sub al, '0'.

  • The loop instruction depends on the CX register and you forgot to initialize it! Don't bother doing it now, since the code can work fine without the loop instruction. Just exit the loop as soon as BL becomes 1. You don't want to multiply by 1 because that's a waste of time.

Up to 5!

Your code that uses the byte-sized multiplication can work for factorials up to 5! (for 6! and up, products would overflow the AL register):

 mov  ah, 01h
 int  21h       ; -> AL=["1","5"]
 sub  al, '0'
 cbw            ; -> AX is [1,5]
 cmp  al, 3
 jb   done
 mov  bl, al    ; [3,5]
fac:
 dec  bl
 mul  bl
 cmp  bl, 2
 ja   fac
done:
 ...

At the ... you would write the code that displays the number from AX and that you can copy from Displaying numbers with DOS.

6! and up

Because 9! is 362880 you will want to use the word-sized multiplication and to avoid any overflow along the road you should start multiplication from 2 up to the inputted digit.
Here you would display the number from DX:AX. Also to be found in Displaying numbers with DOS.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76