News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Fibonacci Sequence MASM code

Started by ISM34, October 23, 2016, 03:30:10 AM

Previous topic - Next topic

ISM34

I am trying to write assembly language code for the following problem:

Write a program that uses a loop to calculate the first seven values of the Fibonacci number sequence described by the following formula: Fib(1) = 1, Fib(2) = 1, Fib(n) = Fib(n -1) +Fib(n-2).

Is my code correct? Also is it okay that I offset the numbers array and move it to the esi register before the loop?:


ExitProcess PROTO

.data

numbers DWORD 7 DUP (?)

.code
main PROC
mov ebx,0
mov edx,1
mov [numbers],edx

mov ecx,7
mov esi,4
mov esi,OFFSET numbers

L1:
mov eax,ebx
add eax,edx
mov [esi],edx
mov ebx,edx
mov edx,eax
add esi,4
Loop L1

call ExitProcess
main ENDP
END



Mikl__

The argument is passed via register EAX, and the value is returned through register EBX:
.code
     mov eax,N ;calculate the N-th Fibonacci number
     call fibonacci ;procedure call
     invoke wsprintf,offset buffer,offset format, ebx
     add esp,12 ; equalize stack after wsprintf
     invoke MessageBox,0,offset buffer,offset caption,MB_OK;outputs the results to the screen
     invoke ExitProcess,0; exit the program
;--------------------------------------
fibonacci proc
; EBX=F(N) - Fibonacci number with the number N (EAX=N)
        cmp eax,1 ;If N> 1, go to the label f
        ja f
        mov ebx,1 ;if N<=1 then EBX=F(N)=1
retn
f:      push eax ;save EAX
        dec eax ;EAX=N-1
        call fibonacci
        push ebx ;save EBX=F(N-1)
        dec eax ;EAX=N-2
        call fibonacci;EBX=F(N-2)
        pop eax ;EAX=F(N-1)
        add ebx,eax ;EBX=F(N)=F(N-2)+F(N-1)
        pop eax ;restore the original value in EAX
        retn
fibonacci endp
;-----------------------------------------
.data
format db 'fibonacci=%u',0
buffer db 50 dup (0)
caption db 'fibonacci',0

mineiro

QuoteIs my code correct?
no
QuoteAlso is it okay that I offset the numbers array and move it to the esi register before the loop?:
Yes, but ...

Check twice both lines below:
   mov esi,4                           ;I think you don't like to mov 4
   mov esi,OFFSET numbers   ;this line of code overwrite the meaning of line above

Check 7 times counter
You're doing first number on numbers table manually before loop, so ...

Check data section and/or variable
.data ==> initialized block (section) data
.data? ==> unitialized block (section) data
numbers DWORD 7 DUP (?) ==> interrogation means inside this scope unitialized data

ExitProcess PROTO

.data                                         ;<------
numbers DWORD 7 DUP (?)      ;<--------

.code
main PROC
mov ebx,0
mov edx,1
mov [numbers],edx         ;first manually

mov ecx,7                        ;starting counter
mov esi,4                         ;supposed to point to next
mov esi,OFFSET numbers         ;reseting esi register to start of numbers table

L1:
mov eax,ebx
add eax,edx
mov [esi],edx
mov ebx,edx
mov edx,eax
add esi,4
Loop L1

call ExitProcess               ;ExitProcess function returns a number
main ENDP
END
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

Mikl__

#3
Saudações, mineiro!
Eu ia escrever mais fácil...
N equ 10
.data
numbers dd 1,1, N-1 dup(?)
format 'fibonacci=%u',0
buffer db 50 dup (0)
caption db 'fibonacci',0
.code
start: mov ecx,N-1
mov esi,offset numbers+4
lea edi,[esi+4]
@@: lodsd
add eax,[esi-8]
stosd
loop @b
invoke wsprintf,addr buffer,addr format,eax
add esp,4*3
invoke MessageBox,0,addr buffer,addr caption,MB_OK
invoke ExitProcess,NULL
end start
ou como esteN equ 9
i = 1
k = 1
rept (N-1)
j = i + k
i = k
k = j
endm
.data
buffer db 50 dup(?)
format db "%u",0
caption db "Fibonacci",0
.code
start: invoke wsprintf,addr buffer,addr format,k
add esp,4*3
invoke MessageBox,0,addr buffer,addr caption,MB_OK
invoke ExitProcess,NULL
end start

Binet's formula (A fórmula de Binet)

N equ 12
.data
buffer db 50 dup(?)
format db "%u",0
caption db "Fibonacci",0
const0_5 dd 0.5
k dd ?
inverse_square_root_from_five dd 0.44721359549995793928183473374626;=1/sqrt(5)
square_root_from_five dd 2.2360679774997896964091736687313;=sqrt(5)
.code
start: fninit
fld1                       ;st=1
fadd square_root_from_five ;st=1+2.23=3.23
fmul const0_5              ;st=3.23/2=1.618
fld st                     ;st(1)=st
mov ecx,N
@@: fmul st,st(1)              ;st=(1.62)^N
loop @b
fmul inverse_square_root_from_five ;st=((1.62)^N)/sqrt(5)
fistp k
invoke wsprintf,addr buffer,addr format,k
add esp,4*3
invoke MessageBox,0,addr buffer,addr caption,MB_OK
invoke ExitProcess,NULL
end start
Binet's formula and fast exponentiation (A fórmula de Binet e exponenciação rápida)N equ 26
.data
buffer db 50 dup(?)
format db "%u",0
caption db "Fibonacci",0
const0_5 dd 0.5
k dd ?
inverse_square_root_from_five dd 0.44721359549995793928183473374626;=1/sqrt(5)
x dd 1.6180339887498948482045868343656;=(1+sqrt(5))/2
.code
start: fninit
fld inverse_square_root_from_five ;st=0.44721359549995793928183473374626
fld x                               ;st=1.6180339887498948482045868343656
mov ecx,N+1                ;st=1.618 st(1)=0.44721
@@: test ecx,1
jz a1
fmul st(1),st             
a1: fmul st,st
shr ecx,1
jnz @b    
fstp st      
fistp k                         ;k=int(((1.62)^N)/sqrt(5))
invoke wsprintf,addr buffer,addr format,k
add esp,4*3
invoke MessageBox,0,addr buffer,addr caption,MB_OK
invoke ExitProcess,NULL
end start

mineiro

I think into russian language man mean "manchini" and woman mean "genchini" phonetically way. Correct me if I'm wrong.

Manchini (Мистер)  Mikl__, you're done elegant solutions. Congratulations.

To me author post is learning assembly language, that's why I don't post code, I only tried to show possible corrections about what I think that he was thinking while coding. My fear is about copy and paste code, I think author post can be doing a homework, I hope you understand me.

Fibonacci sequence it's a nice start. The base is just to count rabbits reproduction but after persons see that can be used to count tree nodes. The Nature is fantastic. We still need a way to count how much years old a tree have. The only solution that I know is cut the tree at base and count how many internall circles (spring) lived that tree.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

Mikl__

mineiro,
мужчина = homem, женщина = mulher, господин = cavalheiro, госпожа = senhora 
any professor likes the student that not only correctly fulfill its mission, but also to know about the subject little more than him ask in the university

ISM34

I appreciate all the help. The code Mikl_ provided is definitely more advanced than I am ready for. However, I am trying to understand it.

BugCatcher

#7
A windowed example.