See below.
fact()
# int fact( int n ) # { # if ( n<=1) # return 1; # else # return n*fact(n-1); # } .text .globl fact fact: # prolog . . . . . . # body of subroutine move $s1,$a0 # save argument in $s1 li $t1,1 # get a 1 bgt $s1,$t1,recurse # if ( n<=1) li $v0,1 # return 1 b epilog recurse: # else # return n*fact(n-1); sub $a0,$s1,1 # argument0 = n-1 # subroutine call # 1. No T registers to push # 2. Argument is in $a0 jal fact # 3. Jump and link to subroutine mul $___,$___,$___ # n*fact(n-1) epilog: # epilog # 1. Return value is already in $v0 . . . . . . jr $ra #
The alternate branch of the if
statement
has the job of calculating n*fact(n-1)
.
It does this by first calculating the argument n-1
.
Then it calls the subroutine fact()
in the normal way.
It does not hurt for fact()
to call fact()
because
each activation has its own data on the stack.
On return from the (inner) call to fact()
,
register $v0
has the returned value, and
register $s1
has the argument n
.
Now the return value from the current activation must be
placed in $v0
to be returned to the caller.