Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .data
- # factorial(n):
- # if n == 0:
- # return 1
- # return n * factorial(n-1)
- startText: .asciiz "Enter a number\n n = "
- endText: .asciiz "n! = "
- invalidText: .asciiz "Invalid number."
- .text
- start:
- puts startText # print the text
- geti $a0 # get the number
- bltz $a0, textIsInvalid # if the number is negative, print the error message and exit
- # -----------------
- # before the call
- # $ra, $fp, $a0 -- the order is important
- subu $sp, $sp, 12 # allocate space for the return address. 12 = 4 * 3 (3 registers) [unsigned subtraction]
- sw $ra, 8($sp) # save the return address. Decrementing offset since we're going *DOWN* the stack
- sw $fp, 4($sp) # save the frame pointer
- # sw, $a0, 0($sp) # we do NOT need to save $a0 because it's done automatically by the jal instruction. Doing so doesn't break anything, but it's redundant.
- addu $fp, $sp, 12 # move FP to the base again.
- # -----------------
- jal Factorial # call the factorial function
- # after the call
- addu $sp, $sp, 12 # pop all the registers we pushed before the call
- display:
- puts endText
- puti $v1
- j finish
- textIsInvalid:
- puts invalidText
- j finish
- finish:
- done
- Factorial:
- subu $sp, $sp, 12 # Same steps as above.
- sw $ra, 8($sp)
- sw $fp, 4($sp)
- sw $a0, 0($sp) # we DO need to save it now
- addu $fp, $sp, 12
- lw $v1, ($sp) # v1 = n
- bgtz $v1, continue # if n > 0, continue
- li $v1, 1 # else, v1 = 1 (return 1)
- j func_finish
- continue:
- lw $a0, 0($sp) # a0 = n
- sub $a0, $a0, 1 # a0 = n - 1
- jal Factorial # call factorial(n-1)
- lw $a0, ($sp) # a0 = n
- mul $v1, $v1, $a0 # v1 = v1 * a0 (v1 = n * factorial(n-1))
- func_finish:
- lw $ra, 8($sp) # restore the return address
- lw $fp, 4($sp) # restore the frame pointer
- addu $sp, $sp, 12 # pop all the registers we pushed before the call
- jr $ra
Advertisement
Add Comment
Please, Sign In to add comment