Search code examples
assemblyx86factorialdosbox

assembly language program to display a factorial of a number is not working


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

Solution

  • 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.