       .align 0
       .data 0x10001000
msg:
        .asciiz "The factorial of 10 is %d\n"


        .text
        .globl main
main:
        subu    $sp, $sp, 32    #stack frame size is 32 bytes
        sw      $ra,20($sp)     #save return address
        sw      $fp,16($sp)     #save frame pointer
        addu    $fp, $sp,32     #set frame pointer       
        li      $a0, 10         #load argument (10) in $a0
        jal     fact            #call fact
        move    $a1, $v0        #store result to $a1
        jal     printf          # call printf

        lw      $ra,20($sp)     # restore $sp
        lw      $fp,16($sp)     # restore $fp
        addu    $sp, $sp,32     # pop the stack
        jr      $ra             # exit()

 
        .text
fact:
        subu    $sp,$sp,32      # stack frame is 32 bytes
        sw      $ra,20($sp)     #save return address
        sw      $fp,16($sp)     #save frame pointer
        addu    $fp, $sp,32     # set frame pointer

        sw      $a0,0($fp)      # save argument(n)

        lw      $v0,0($fp)      # load n
        bgtz    $v0,$L2         # if n>0 go to $L2
        li      $v0,1           #
        j       $L1             # return(1)

$L2:
        lw      $v1, 0($fp)     # load n
        subu    $v0,$v1,1       # compute n-1
        move    $a0,$v0         # load argument (n-1) in $a0
        jal     fact            # call fact

        lw      $v1,0($fp)      # load n
        mul     $v0,$v0,$v1     # fact(n-1)*n

$L1:                            # return code
        lw      $ra,20($sp)     # restore $ra
        lw      $fp, 16($sp)    # restore $fp
        addu    $sp,$sp,32      # pop the stack
        jr      $ra             #return, result in $v0


printf: subu    $sp,$sp,32      # stack frame is 32 bytes
        sw      $ra,20($sp)     #save return address
        sw      $fp,16($sp)     #save frame pointer
        addu    $fp, $sp,32     # set frame pointer
        
        li      $v0, 4          #\
        la      $a0, msg        # >  Print a string
        syscall                 #/
        li      $v0, 1          #\
        move    $a0, $a1        # >  Print a number
        syscall                 #/
        
        lw      $ra,20($sp)     # restore $ra
        lw      $fp, 16($sp)    # restore $fp
        addu    $sp,$sp,32      # pop the stack
        jr      $ra             #return, result in $v0







