Here is my CS170 webpage that explain what Fibonacci was doing when he formulated the equation for Fibonacci number: click here
int fib(int n)
{ int help1, help2;
if (n = 0)
return 1;
else if (n == 1)
return 1;
else
{ help1 = fib(n-1);
help2 = fib(n-2);
return help1+help2;
}
}
int n, result; result = fib(n);
+---------------------+ <------------ Stack pointer (A7) | use for help2 var | +---------------------+ | use for help1 var | +---------------------+ <------------ Frame Pointer (A6) | Saved Frame Pointer | +---------------------+ | Return Address | +---------------------+ | use for parameter n | +---------------------+ | ....... | | rest of the stack | | ....... |
The main program passes the parameter n to Fibonacci by pushing n onto the system stack with the following instruction:
move.l n, -(a7)
This will create the following stack structure:
+---------------------+ <------------ Stack pointer (A7) | parameter n | +---------------------+ | ....... | | rest of the stack | | ....... |
The main program calls the Fibonacci function with a bsr instruction:
bsr fib
This will create the following stack structure:
+---------------------+ <------------ Stack pointer (A7) | return address | +---------------------+ | parameter n | +---------------------+ | ....... | | rest of the stack | | ....... |
The prelude of the Fibonacci function consists of these 3 instructions:
********************************* PRELUDE
move.l a6, -(a7) ; Save caller's frame pointer
move.l a7, a6 ; Setup my own frame pointer
suba.l #8, a7 ; Allocate space for help1 & help2
*********************************
I will explain what each one does below.
Make sure that you realise that the structure of the stack frame is
like this when the prelude is always executed:
+---------------------+ <------------ Stack pointer (A7) | return address | +---------------------+ | parameter n | +---------------------+ | ....... | | rest of the stack | | ....... |
This will save the frame pointer on the stack, creating this partial stack frame structure:
+---------------------+ <------------ Stack pointer (A7) | saved a6 | +---------------------+ | return address | +---------------------+ | parameter n | +---------------------+ | ....... | | rest of the stack | | ....... |
This will make the frame pointer A6 points to the stack frame that is now being built:
+---------------------+ <---- Frame pointer A6 & Stack pointer (A7) | saved a6 | point to the same location.... +---------------------+ | return address | +---------------------+ | parameter n | +---------------------+ | ....... | | rest of the stack | | ....... |
This will push the stack pointer A7 8 bytes up, allocating 2 integer variables. How these variables will be used is upto the discretion of the programmer. In the program, I will use the lower one for help1 and the upper one for help2.
+---------------------+ <---- Stack pointer (A7) | help2 | +---------------------+ | help1 | +---------------------+ <---- Frame pointer (A6) | saved a6 | +---------------------+ | return address | +---------------------+ | parameter n | +---------------------+ | ....... | | rest of the stack | | ....... |
So the address mode that will let you get to this variable is 8(A6)
So the address mode that will let you get to this variable is -4(A6)
So the address mode that will let you get to this variable is -8(A6)
It is no different from how the main program calls the Fibonacci function. Simply push the parameter on the stack, and call Fibonacci.
But make sure you pop the parameter from the stack after Fibonacci returns - because the parameter has not been cleaned up.
The following is the program fragment where Fibonacci calls fib(n-1):
move.l 8(a6), d0 ; retrieve parameter n into register d0
sub.l #1, d0 ; d0 = n - 1
*
* ----------------------------- ; fib is calling fib now !!!!
*
move.l d0, -(a7) ; Push (n-1) as parameter
bsr fib ; Call fib(n-1)
adda.l #4,a7 ; Clean up parameter from stack
move.l d0, -4(a6) ; help1 = return value of fib(n-1) in register D0
Fibonacci will call itself a second time with value n-2. The following is the program fragment where Fibonacci calls fib(n-2):
move.l 8(a6), d0 ; retrieve parameter n into register d0
sub.l #2, d0 ; d0 = n - 2
*
* ----------------------------- ; fib is calling fib again....
*
move.l d0, -(a7) ; Push (n-2) as parameter
bsr fib ; Call fib(n-2)
adda.l #4,a7 ; Clean up parameter from stack
move.l d0, -8(a6) ; help2 = return value of fib(n-1) in register D0
I have highlighted the difference between the first call and the second.
The second call uses a different parameter value and stores
the return value in a different local variable !