# factorial.spim --- A recursive SPIM program. Demonstrates function # call and return. .data prompt: .asciiz "Number: " nl: .asciiz "\n" instr: .asciiz "Enter 0 to exit.\n" response: .asciiz "Factorial: " ###################################################################### # main ###################################################################### .text .globl main main: sub $sp, $sp, 16 # Push frame & save registers. sw $fp, 16($sp) sw $ra, 12($sp) sw $s0, 8($sp) add $fp, $sp, 16 li $v0, 4 # Print instruction. la $a0, instr syscall jal getnum # Get a number from keyboard. sw $v0, -12($fp) # Store locally. move $s0, $v0 while1: beqz $s0, endwhile1 # Compute until 0 entered. li $v0, 4 # Print response prompt. la $a0, response syscall move $a0, $s0 # Pass argument jal factorial # Call move $a0, $v0 # Copy return value to print it li $v0, 1 syscall li $v0, 4 # Prepare to read next number. la $a0, nl syscall jal getnum sw $v0, -12($fp) # Store number just read. move $s0, $v0 b while1 endwhile1: lw $s0, 8($sp) # Restore registers and pop frame. lw $ra, 12($sp) lw $fp, 16($sp) add $sp, $sp, 16 li $v0, 0 jr $ra # Exit. ###################################################################### # getnum --- returns integer read from keyboard through $v0. ###################################################################### .text getnum: sub $sp, $sp, 12 # push frame & save registers. sw $fp, 12($sp) sw $ra, 8($sp) add $fp, $sp, 12 li $v0, 4 la $a0, prompt syscall li $v0, 5 syscall # Value read left in $v0. sw $v0, -8($fp) lw $ra, 8($sp) # restore registers & pop frame. lw $fp, 12($sp) add $sp, $sp, 12 jr $ra ###################################################################### # factorial --- compute factorial of $a0 and return result through # $v0 ###################################################################### .text factorial: sub $sp, $sp, 16 sw $fp, 16($sp) sw $ra, 12($sp) sw $s0, 8($sp) add $fp, $sp, 16 sw $a0, -12($fp) # Our value n. move $s0, $a0 bgt $s0, 1, recurse # Base case. Return 1 li $v0, 1 lw $s0, 8($sp) lw $ra, 12($sp) lw $fp, 16($sp) add $sp, $sp, 16 jr $ra recurse: sub $a0, $a0, 1 # Recursive call. Compute (n-1)! jal factorial mul $v0, $v0, $s0 # n * (n-1)! lw $s0, 8($sp) lw $ra, 12($sp) lw $fp, 16($sp) add $sp, $sp, 16 jr $ra