Reputation: 1
I am new to MIPS and I have a given MIPS recursive code which I have to apply it to a specific number (ex. number 3) Bellow is the given MIPS code and I am supposed to write if I were to pass ex. number 3 in the function what would be the changes in the registries and cache for the recursion for said number 3? I have tried to do it step by step on a piece of paper but got nowhere.
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0,$a0,1
beq $t0,$zero,L1
addi $v0,$zero,1
addi $sp,$sp,8
jr $ra
Ll:addi $a0,$a0,-1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0,$a0,$v0
jr $ra
Upvotes: 0
Views: 131
Reputation: 26646
Always test your code with the smallest possible input first. If you try with 0, and single step some 8 instructions worth, you can observe that your code doesn't return to its caller with the proper stack pointer value — an important part of functions is to preserve the registers that must be preserved for the caller, and that includes the stack pointer. Usually, the way to restore the stack pointer is to deallocate any allocated space, and as long as this is balanced, the preservation rule for $sp
is honored.
As a result of an improper stack pointer, the caller is messed up. Where this bites you, then is when the caller tries to return to its caller. Likely this is not a problem for main
b/c on MARS, for example, we usually exit main
via the exit syscall. However, if you do fact(2)
, you'll see that the first return it executes works ok, but after that the caller (fact itself, recursive caller) doesn't work — it is unable to return to its caller, because it cannot properly restore its previously preserved $ra
, because the stack pointer has been unbalanced by the terminal case.
We need to balance prologue with epilogue: not just statically but dynamically.
Your code is allocating stack space in all cases, though in the terminal case, your code is omitting the deallocation of the stack, so it becomes unbalanced.
Either add stack adjustment (deallocation) to the terminal case, or, test for the terminal case before even allocating stack space (so you don't have to either allocate or deallocate in that terminal case).
Upvotes: 2