.model  SMALL
.stack  128
.data
        STRINGIN        LABEL   BYTE
        MAX_LEN         DB      2
        ACT_LEN         DB      ?
        NUMBER  DB      3 DUP('0')

        MSG1    DB      'FACT IS :','$'

.code
        MAIN    PROC

                ;set data segment
                MOV     AX,@data
                MOV     DS,AX

                ;read number from keyboard
                MOV     AH,0AH
                LEA     DX,STRINGIN
                INT     21H

                ;push number and result in to stack
                MOV     AX,0H
                MOV     AL,NUMBER[0]
                SUB     AL,30H
                PUSH    AX
                MOV     BX,0H
                PUSH    BX

                ;call function fact
                CALL    FACT

                ;give result from stack in BX
                POP     BX
                POP     AX

                ;divide result to 100
                MOV     AX,BX
                MOV     CL,100
                DIV     CL

                MOV     BX,AX

                ;display message
                MOV     AH,09H
                LEA     DX,MSG1
                INT     21H

                ;print 3th digit
                MOV     AH,02H
                MOV     DL,BL
                ADD     DL,30H
                INT     21H

                ;divide to 10
                MOV     AL,BH
                MOV     AH,0H
                MOV     CL,10
                DIV     CL

                ;change ascii number to character
                MOV     BX,AX
                ADD     BX,3030H

                ;print 2nd and 1st digit
                MOV     AH,02H
                MOV     DL,BL
                INT     21H
                MOV     AH,02H
                MOV     DL,BH
                INT     21H

                ;end of main
                MOV     AX,4C00H
                INT     21H


        MAIN    ENDP

        FACT    PROC    NEAR

                ;set BP to top of stack
                PUSH    BP
                MOV     BP,SP

                ;give number from stack
                ;compare it with zero
                MOV     AX,[BP+6]
                CMP     AX,0
                JNE     NOT_EQUAL_ZERO
                MOV     [BP+4],WORD PTR 0001H
                POP     BP
                RET

           NOT_EQUAL_ZERO:

                ;ready to recersive call
                DEC     AX
                PUSH    AX
                MOV     BX,0
                PUSH    BX

                ;call recersive function
                CALL    FACT

                ;give (n-1)! to BX & (n-1) to AX from stack
                POP     BX
                POP     AX

                ;change (n-1) to n
                INC     AX

                ;multiply n*(n-1)!
                MUL     BX

                ;put result into stack
                MOV     [BP+4],AX

                ;pop BP
                POP     BP

                ;return to parent function
                RET

        FACT    ENDP

        END     MAIN
