So I am creating a program to give the nth term of the Fibonacci sequence. I am supposed to implement the following logic using recursive MASM assembly.
int fib(int n){
if ((n == 1) || (n == 2))
return n - 1;
else
return fib(n-1) + fib(n-2);
}
The issue I seem to be having is retaining the values as the program cycles through until reaching 1. I am fairly unexperienced with recursion and I feel like I am missing something in that aspect. I am not sure how to retain the values to add them.
.code
main PROC
mov ecx,0
push 4 ; calculate the nth fib
call Fib ; calculate fib (eax)
call WriteDec
call Crlf
exit
main ENDP
Fib PROC
add ecx,1
push ebp
mov ebp,esp
mov eax,[ebp+8] ; get n
cmp eax,2 ; n == 2?
je exception2
cmp eax,1 ; n == 1?
je exception2
dec eax
push eax ; Fib(n-1)
call fib
add eax,
jmp Quit
Exception2:
dec eax
Quit:
pop ebp ; return EAX
ret 4 ; clean up stack
Fib ENDP
END main
At the end of the procedure you must restore ESP
not only EBP
.
ret 4
(stdcall) is in this case not convenient because you can reuse the value on the stack for the second call.
For the result of the first call you can use a local variable which will be created on the "current" stack.
Don't mix lower and upper case in symbols even if an OPTION-directive allows it!
I changed your code accordingly:
include Irvine32.inc
.code
main PROC
mov ecx,0
push 10 ; calculate the nth fib
call fib ; calculate fib (eax)
add esp, 4 ; clean up the stack
call WriteDec
call Crlf
exit
main ENDP
fib PROC C
add ecx,1
push ebp
mov ebp,esp
sub esp, 4 ; space for a local dword [ebp-4]
mov eax,[ebp+8] ; get n
; if ((n == 1) || (n == 2)) return 1;
cmp eax,2 ; n == 2?
je exception2
cmp eax,1 ; n == 1?
je exception2
;else return fib(n-1) + fib(n-2);
dec eax
push eax ; Fib(n-1)
call fib
mov [ebp-4], eax ; store first result
dec dword ptr [esp] ; (n-1) on the stack -> (n-2)
call fib
add esp, 4 ; clean up stack
add eax, [ebp-4] ; add result and stored first result
jmp Quit
exception2:
mov eax, 1 ; start values: 1, 1
; dec eax ; start values: 0, 1
Quit:
mov esp, ebp ; restore esp
pop ebp ; restore ebp
ret ; return EAX, stack not cleaned up
fib ENDP
END main