- Mar 21, 2009
- 409
- 2
- 81
I am trying to teach myself underlying computer concepts with the help of Computer Organization and Design 3rd Edition. In it the authors use the 32bit MIPS Assembly language and architecture to teach concepts.
I am on Section 2.7 which covers Stacks, procedures, and nested procedures using a sort of sudo assembly language that is has presented thus far. This is the problem it presents step by step with explanations:
I understand that the original value for n or argument $a0 is stored in the stack before L1 procedure is executed. My problem is when the recursion happens I don't see how the new value of n (n-1) makes it into the equation. I am assuming that the multiply command:
mul $v0, $a0, $v0
Contains the modified value and the original value (or the last value used before being decremented).
If this equation recurs twice; once for the initial call and one for a nested call, then where does n-1 go? Further more if it recurs three or more times, then where is the intermediate value stored? In the stack and the beginning of each time through L1? That is the part I am confused about.
I am on Section 2.7 which covers Stacks, procedures, and nested procedures using a sort of sudo assembly language that is has presented thus far. This is the problem it presents step by step with explanations:
Computer Organization and Design said:COMPILING A RECURSIVE C PROCEDURE, SHOWING NESTED PROCEDURE LINKING
Let's tackle a recursive procedure that calculates factorial:
int fact (int n)
{
if (n<1) return (1);
else return (n * fact(n-1));
}
What is the MIPS assembly code?
The parameter variable n corresponds to the argument register $a0. The compiled program starts with the label of the procedure and then saves two registers on the stack, the return address and $a0:
fact:
addi $sp, $sp, -8 #adjust stack for 2 items
sw $ra, 4($sp) # save the return address
sw $a0, 0($sp) # save the argument n
The first time fact is called, sw saves an address in the program called fact. The next two instructions test if n is less then 1, going to L1 f N>=1.
slti $$t0, $a0, 1 #test for n < 1
beq $t0, $zero, L1 #if n>= 1, go to L1
If n is less then 1, fact returns 1 by putting 1 into the value register: it adds 1 to 0 and places the sum in $v0. If then pops the two saved values off the stack and jumps to the return address:
addi $v0, $zero, 1 #returns 1
addi $sp, $sp,8 # pop 2 items off the stack
jr $ra # returns to after jal
Before popping two items off the stack, we could have loaded $a0 and $ra. Since $a0 and $ra don't change when n is less then 1, we skip those instructions.
If n is less then 1, the argument n is decremented and then fact is called again with the decremented value:
L1: addi $a0, $a0, -1 #n >=1: argument gets (n-1)
jal fact # call fact with (n-1)
The next instruction is where fact returns, Now the old return address and the old argument are restored, along with the stack pointer:
lw $a0, 0($sp) #return from jal: restore argument n
lw $ra, 4($sp) #restore the return address
addi $sp, $sp, 8 #adjust the stack pointer to pop 2 items
Next, the value register $v0 gets the product of the old argument $a0 and the current value of the value register. We assume a muliply instruction is available, eve though it is not covered tell chapter 3:
mul $v0, $a0, $v0 #return n * fact (n-1)
Finally, fact jumps again to the return addresss:
Jr $ra #returns to caller
I understand that the original value for n or argument $a0 is stored in the stack before L1 procedure is executed. My problem is when the recursion happens I don't see how the new value of n (n-1) makes it into the equation. I am assuming that the multiply command:
mul $v0, $a0, $v0
Contains the modified value and the original value (or the last value used before being decremented).
If this equation recurs twice; once for the initial call and one for a nested call, then where does n-1 go? Further more if it recurs three or more times, then where is the intermediate value stored? In the stack and the beginning of each time through L1? That is the part I am confused about.