# fun fact(x:int):int = # if (x) < 1 then 1 # else (x * fact(x-1) ) # in # let a = fact(10) in # printint a # .data NL: .asciiz "\n" .text main: addi $sp, $sp, -4 # push initial stack frame sw $ra, 0($sp) # save return address jal init # initialize allocator li $v0, 10 # move factorial argument into place move $a0, $v0 jal _fact # run fact function move $v1, $v0 # save result of fact li $v0, 1 # set up system call to print result move $a0, $v1 syscall li $v0, 4 # set up system call to print newline la $a0, NL syscall lw $ra, 0($sp) # retrieve saved return address addi $sp, $sp, 4 # pop initial stack frame jr $ra # end simulation _fact: # argument arrives in $a0 addi $sp, $sp, -8 # allocate activation record sw $ra, 4($sp) # save return address sw $s0, 0($sp) # callee save register $s0 move $s0, $a0 # move argument to $s0 li $v0, 1 # load 1 bge $s0, $v0, L2 # if 1 > x then jump to L2 else fall to L1 L1: li $v0, 1 # answer is 1 j L3 # jump to L3 L2: li $v0, 1 # load 1 sub $v0, $s0, $v0 # subtract from x move $a0, $v0 # move x to arg position for recursive call jal _fact move $v0, $v0 # very superfluous move instruction! mulo $v0, $s0, $v0 # multiply result of fact by x move $v0, $v0 # very superfluous move instruction! L3: # returning from function move $v0, $v0 # very superfluous move instruction! lw $ra, 4($sp) # retrieve return address lw $s0, 0($sp) # retrieve callee save register addi $sp, $sp, 8 # pop fact's stack frame jr $ra # return alloc: # allocate data addi $sp, $sp, -4 sw $ra, 0($sp) move $v0, $s7 add $s7, $s7, $a0 lw $ra, 0($sp) addi $sp, $sp, 4 jr $ra init: # initialize heap/gc addi $sp, $sp, -4 sw $ra, 0($sp) li $v0, 9 li $a0, 32000 syscall move $s7, $v0 lw $ra, 0($sp) addi $sp, $sp, 4 jr $ra