; fibo.asm ; ; This program calculates and displays terms of the Fibonacci ; series by using nineteenth century French mathemetician Edouard ; Lucas' formula: ; ; n n ; x[n] = (phi + (-1/phi) ) / sqrt(5) ; ; phi is the so-called "golden number" and is defined as: ; ; phi = (1 + sqrt(5))/2 ; ; This program was written on Sun 02-15-1998 by Ed Beroset ; and is released to the public domain by the author. ; .model tiny .code .586 LIMIT = 86 org 100h start: xor ax,ax ; more2: inc ax push ax ; save the term number (n) call fibo ; calculate x[n] call showres ; show it on screen pop ax ; cmp ax,LIMIT ; calculate lots of terms jb more2 ; mov ax,4c00h ; DOS exit int 21h ; ; ; fibo ; ; calculates the nth term of the Fibonacci series in a non-iterative ; manner. ; ; IN: ax = n (the term number, where 0 < n < 87) ; ; OUT: ; dx:ax = x[n] ; for test purpose, the variable named zulu is filled with the ; BCD equivalent ; fibo proc push 5 mov bp,sp fild word ptr [bp] fsqrt ; st(0) = sqrt(5) = k push ax ; fild word ptr [bp-2] ; n, k fld st(1) ; k, n, k fld1 ; 1, k, n, k fadd st(1),st ; 1, 1+k, k, n, k fadd st,st(0) ; 2, 1+k, n, k fdivp st(1),st ; (1+k)/2, n, k fyl2x ; n*log2((1+k)/2), k fld st(0) ; frndint ; int, x, k fsub st(1),st(0) ; int, frac, k fxch st(1) ; frac, int f2xm1 ; ((1+k)/2)**n - 1, exp, k fld1 ; 1, ((1+k)/2)**n - 1, exp, k faddp ; ((1+k)/2)**n, exp, k fscale ; ((1+k)/2)**n, k fld1 ; 1, ((1+k)/2)**n, k fld st(1) ; ((1+k)/2)**n, 1, ((1+k)/2)**n, k fdivp ; 1/(((1+k)/2)**n), ((1+k)/2)**n, k shr al,1 ; Q: is n an odd number? jnc notodd ; N: no, so skip fchs ; Y: change sign of inverse term notodd: faddp ; x, int, k fxch st(1) ; int, x, k ffree st ; --, x, k fincstp ; x, k fdivrp ; push eax ; fld st ; fistp qword ptr [bp-6]; save the result fbstp tbyte ptr [zulu]; save BCD result pop eax ; in edx:eax pop edx ret endp showres proc mov cx,18 mov si,offset zulu + 18 - 1 mov di,offset number mov byte ptr [di],0 ; store a NUL to start std ; make 'em decrement more: lodsb ; mov ah,al ; shr al,4 ; and ah,0fh ; or ax,3030h ; mov [di],ax ; inc di ; inc di ; skip: loop more ; mov ax,0a0dh ; CRLF mov [di],ax ; inc di ; inc di ; mov cx,di ; mov di,offset number; sub cx,di ; cld ; mov al,'0' ; suppress leading zeroes repe scasb ; mov dx,di ; dec dx ; inc cx ; mov bx,1 ; write to stdout mov ah,40h ; int 21h ; ret endp .data zulu db 18 dup (?) ; number db 38 dup (?) ; end start