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 fibThis 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 D0I 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 !