# # Spim program that computes factorials using a multiply # subroutine(we haven't covered mul yet!) # # An example of subroutines including a recursive subroutine. .data msg: .asciiz "The answer is " .text # this is program code .align 2 # instructions must be on word boundaries .globl main # main is a global label main: addi $a0,$zero,6 # call factorial(6) jal factorial move $s0,$v0 # get the answer and save it li $v0,4 # print out msg la $a0, msg syscall li $v0,1 # print the answer move $a0,$s0 syscall li $v0,10 # exit syscall # ------------------------------------- # # factorial is a recursive procedure. It uses the multiply # subroutine to do multiplication... # to call - load up $a0 with a number x, it returns # the factorial(x) in $v0. factorial: sub $sp,$sp,8 # make room for 2 registers sw $ra,0($sp) # save the return address sw $a0,4($sp) # save x slti $t0,$a0,1 # is x < 1 ? bne $t0,$zero,L1 # yes - go to L1 sub $a0,$a0,1 # x--; jal factorial # call fact(x-1) # Now multiply the result by x # a0 is no longer x, but we still have it on the stack lw $a0,4($sp) add $a1,$v0,$zero # $v0 is fact(x-1) jal multiply # get the product # restore $a0 and $ra before returning # multiply may have changed $a0 (so we must restore again) # $v0 is already the return value lw $a0,4($sp) lw $ra,0($sp) add $sp,$sp,8 # restore the stack jr $ra L1: # x<1 so we just return 1 addi $v0,$zero,1 # $a0 and $ra have not changed, no need to restore add $sp,$sp,8 # but we need to restore the stack jr $ra #------------------------------------ # mult subroutine needs some registers # so we save $t0 first # # to call - put the multiplicands in $a0 and $a1, # the product is returned in $v0 # # no overflow checking done! multiply: # start with $t0 = 0 add $t0,$zero,$zero mult_loop: # loop on a1 beq $a1,$zero,mult_eol add $t0,$t0,$a0 sub $a1,$a1,1 j mult_loop mult_eol: # put the result in $v0 add $v0,$t0,$zero jr $ra # return