linux - NASM Assembly recursive fibonacci -
learning nasm assembly on 32-bit ubuntu.
i've been learning recursive functions. did factorial, here: understanding recursive factorial function in nasm assembly
watching code, thought maybe implement fibonacci well, using same code. here code, assuming parameter greater 0
:
section .text global main main: ; ----------------------------------------------------------- ; main ; ----------------------------------------------------------- push 6 call fibonacci mov [ecx],eax add byte [ecx],'0' mov edx,1 call print ; ----------------------------------------------------------- ; exit ; ----------------------------------------------------------- mov eax,1 int 0x80 ; ----------------------------------------------------------- ; fibonacci recursivo: f(n) = f(n - 1) + f(n - 2) ; ----------------------------------------------------------- fibonacci: push ebp ; retrieve parameter , put push ebx ; save previous parameter mov ebp,esp ; ebx register add ebp,12 ; mov ebx,[ebp] ; ebx = param cmp ebx,1 ; check base case jle base ; base if (n <= 1) dec ebx ; decrement ebx put in stack push ebx ; put (ebx - 1) in stack inc ebx ; restore ebx call fibonacci ; calculate fibonacci (ebx - 1) mov esi,eax ; eax = (eax + ebx) pop ebx ; retrieve ebx stack sub ebx,2 ; decrement ebx put in stack push ebx ; put (ebx - 2) in stack add ebx,2 ; restore ebx call fibonacci ; calculate fibonacci (ebx - 2) mov edx,eax ; eax = (eax + ebx) pop ebx ; retrieve ebx stack add esi,edx mov eax,esi jmp end base: ; base case mov eax,1 ; result 1 end: pop ebx ; restore previous parameter pop ebp ; release ebp ret
it bit crude. calculate fibonacci (parameter - 1)
, again (parameter - 2)
, , add them , put them eax
.
it doesn't work:
2 => 2 3 => 3 4 => 4 5 => 4
fortunately fixed segmentation fault errors, broke else doing that. don't see what's problem. can tell me why getting wrong values?
one particular observation that, reason, doing mov ecx,eax
gave me segmentation fault error. that's why used esi
instead. i'm not sure why, guess related.
whenever you're dealing recursion, have careful next layer in recursive chain state of current layer (e.g. register values). i'd suggest rewriting function follows:
fibonacci: push ebp ; retrieve parameter , put push ebx ; save previous parameter mov ebp,esp ; ebx register add ebp,12 ; mov ebx,[ebp] ; ebx = param cmp ebx,1 ; check base case jle base ; base if (n <= 1) lea ecx,[ebx-1] push ecx ; push n-1 call fibonacci ; calculate fibonacci (ebx - 1) pop ecx ; remove n-1 off stack push eax ; save result of fibonacci(n-1) lea ecx,[ebx-2] push ecx ; push n-2 call fibonacci ; calculate fibonacci (ebx - 2) pop ecx ; remove n-2 off stack pop ecx ; ecx = fibonacci(n-1) add eax,ecx ; eax = fibonacci(n-2) + fibonacci(n-1) jmp end base: ; base case mov eax,1 ; result 1 end: pop ebx ; restore previous parameter pop ebp ; release ebp ret
Comments
Post a Comment