The MASM Forum Archive 2004 to 2012

Miscellaneous Forums => 16 bit DOS Programming => Topic started by: ilian007 on November 25, 2009, 06:49:52 AM

Title: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 06:49:52 AM
Hello I am trying to create a program which will use 3 Arrays to calculate fibonacci numbers. It have to start with 1 and 1 in Arr1 and Arr2 and go up to 72 digit in Arr3 then msg overflow. However I can not find a way to deal with the carry properly when numbers get to 2 digits and up. Please help with some Ideas. Please take in mind it is a 16bit topic and I  am a beginner. Thank you. Here is what I have so Far. Thank you. I hardcoded CX to be 7 to make it work with 7th element ...

;===================================================================
   INCLUDE PCMAC.INC       
     .MODEL  small,basic
      .586
      .STACK 100
   
;===================================================================
                                       ;PROCEDURES TO
             
      
      EXTRN   CLEAR:FAR     ;CLEAR SCREEN
      EXTRN   NEWLINE:FAR    ;DISPLAY NEWLINE CHARACTER
           EXTRN   GETDEC$:FAR     ;GET 16-BIT DECIMAL FROM KBD
      EXTRN   PUTDEC$:FAR     ;DISPLAY 16-BIT DECIMAL INT
      EXTRN   GETDEC:FAR
      EXTRN   PUTDEC:FAR
      EXTRN   PUTBIN:FAR     ;DISPLAY 16BIT BINARY INT
           EXTRN   PUTOCT:FAR     ;DISPLAY 8-BIT NUMBER
      EXTRN   PUTSTRNG:FAR   ;DISPLAY CHARACTER STRING

   
;===================================================================
;DATA  S E G M E N T   D E F I N I T I O N
;
     .DATA
MyArr1   DB 72 dup (0)
MyArr2   DB 72 dup (0)
MyArr3   DB 72 dup (0)
Carry    DB  0
   
          
.CONST
SPACES DB ' '

;===================================================================
;C O D E   S E G M E N T   D E F I N I T I O N
;
            .CODE
       ASSUME  DS:DGROUP
;===================================================================
MAIN PROC

        MOV     AX,DGROUP ;SET DS-REGISTER TO POINT TO
        MOV     DS,AX        ;CONSTANT DATA SEGMENT
   MOV     ES,AX      ;SET ES-REGISTER
   CALL    CLEAR
   MOV DI,71
   
   MOV [myarr1+DI],1  ;start sequence at 1, 1
   MOV [myarr2+DI],1
   MOV CX,7
Adding:
   DEC CX
   CMP CX,0
   JZ print
   MOV DI,71
   MOV AX,0
   MOV BX,0
      
   MOV AL,[myarr1+DI]
   ADD AL,[myarr2+DI]
   CMP AL,9
   JA Carryloop
   
   
   
nocarry:
   MOV [MyArr3+DI],AL   ; Arr3 = Arr2 + Arr1
   MOV BL,[Myarr2+DI] 
   MOV [MyArr1+DI],BL   ;MOV value of Arr2 to Arr1
   MOV [MyArr2+DI],AL   ;mov Value of arr3 to arr2
   Dec DI
   jmp adding

carryloop:
   SUB AL,10
   MOV [Myarr3+DI],AL
   MOV carry,1
   DEC DI
   MOV AL,Carry
   Add [myarr3+DI],AL
   jmp adding
Print:
   mov di,1
printt:
   mov AX,0
   MOV AL,[MyArr3+DI]
   CALL PUTDEC
   inc DI
   cmp DI,71
   ja endd
   jmp printt
   
ENDD:   

   

.EXIT
MAIN ENDP                       
        END    MAIN
Title: Re: Fibonacci Numbers Using Arrays
Post by: FORTRANS on November 25, 2009, 01:17:20 PM
Hi,


   MOV carry,1
   DEC DI
   MOV AL,Carry
   Add [myarr3+DI],AL
   jmp adding


   At first glance you are not checking for a carry here.  It
may be caught later when you check for greater than 9,
but it seems easier to propagate the carry through the
array all at once.  The ASCII Adjust for Addition instruction
(AAA) is exactly what you need to keep an array of unpacked
BCD numbers updated.  Assuming that you are allowed to
use it of course.

   The following is an update loop from some of my code.
The loop updates five digits rather than 72, but it should make
sense.


        MOV     BX,OFFSET Dec_Wrk+4 ; Destination for Decimal bytes.
        MOV     CX,5            ; Five bytes in integer.
        CLC                     ; Clear carry for the first add.

UpD_3:  ; Loop over the 5 digits for the current bit adding the numbers up.
        MOV     AL,CS:[BP]      ; New number
        ADC     AL,[BX]         ; Total sum
        AAA                     ; Adjust unpacked BCD
        MOV     [BX],AL         ; save new sum
        DEC     BX              ; INC/DEC don't affect carry.
        DEC     BP
        LOOP    UpD_3           ; LOOP doesn't affect carry.


   Adding two digits with the carry, adjusting the result to
be a valid single digit, with a possible carry, and store the
result.  Then loop to process the rest of the array.  I have
two arrays, you have three, so adjust the store.

HTH,

Steve N.

Edit:

P.S.  If the carry is set after the loop, you overflowed the
array.

SRN
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 04:44:17 PM
We are not allowed to use unpacked BCD or any sort of it for that one. One of our next exercises uses BCD. Teachers idea is to show us the difference. My problem is I have to start adding always from the 72st digit of the array I can not get it how the program will go left to 47th or some digit where it needs to go. like if I have to add


000000000000000000000000000034124141221412412
000000000000000000000000000043214125435235124
0000000000000000000000000 Added

I can not get it how the loop will go left thru the arrays and calculates. I can go through it if it steps just once thru each index. but sometimes it has to step more than once like

00000000000000000000000000000001
00000000000000000000000000000001
00000000000000000000000000000002

00000000000000000000000000000001
00000000000000000000000000000002
00000000000000000000000000000003

has to step a few times thru the 72th digit and then to go to 71st ... 
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 05:33:34 PM
QuoteWe are not allowed to use unpacked BCD or any sort of it for that one.

are they ASCII numeric characters, then ?
by "unpacked BCD", we mean bytes with binary values from 0 to 9
"packed BCD" - they put 2 BCD digits in each byte

we can't tell what you are using because the code shows no initialization of the array values
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 06:14:08 PM
Ded.
Unfortenatelly, I dont know what I am using or what I have to use. Teacher gave us 3 arrays and said: add first 2 together and put result in 3rd one. If u get number >9 substract it from 10 add result to A3 and add 1 to carry. and thats for 72 digit arrray ..
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 06:27:35 PM
lol
well - just a guess, here - i would say that they are unpacked BCD digits
if they are not, they should be converted to unpacked BCD
if you have ASCII numeric characters, that is a simple matter of XOR'ing or SUB'ing 30h from the ASCII to get BCD
i see a little problem with Steve's code
that is that i don't see where the carry after AAA that is created in AH is applied to the next pass
http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-2.html#HEADING2-133
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 06:28:37 PM
I Believe I will have to move to next index after each adding operation no matter if there is carry or no. And to stop when a1 + a2 equal to 0 and move back to 72 element (start position)
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 06:32:19 PM
Ded, yeah by what I see I guess it is unpacked BCD. I will do a little bit more research
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 06:34:25 PM
if i understand what you are saying, the instructor does not want you to use the AAA instruction
he/she wants you to handle the carry into the next digit, "manually"
give me a few minutes to write a little loop....
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 06:45:05 PM
        mov     di,71           ;index to last digit
        mov     bx,10           ;bl = 10, bh = 0
        mov     ah,bh           ;clear the carry
        mov     cx,72           ;digit count

add_loop:
        mov     al,MyArr1[di]   ;digit from value 1
        add     al,MyArr2[di]   ;add digit from value 2
        add     al,ah           ;add carry from previous pass
        mov     ah,bh           ;clear out the old carry
        cmp     al,bl           ;is it > 9 ?
        jb      no_carry        ;no - skip carry

        sub     al,bl           ;subtract 10
        inc     ah              ;set carry

no_carry:
        mov     MyArr3[di],al
        dec     di
        loop    add_loop

;if ah = 1 at this point, the accumulator has overflowed
Title: Re: Fibonacci Numbers Using Arrays
Post by: FORTRANS on November 25, 2009, 06:53:22 PM
Hi,

   Dave the carry is in the flags.  I ignore AH as it's not
useful here.

   MGG, okay, what you are doing is what the AAA does
anyway.  If the number is grater than 9, subtract 10 and
propagate the carry.  You just need to change your loop
structure a bit.  Pseudo code follows.


Normal setup
        Outer loop, do the Fibonacci adds
        (Debug, do a fixed number, later until overflow.)
        Clear carry, set up starting addresses, set count for inner loop, etc..

                Inner loop, do the addition over all elements in the array.
                add with carry ( or as you were doing, keep track in a variable )
                Emulate AAA as you were doing
                        Check if greater than 9
                        if so, sub 10, and set carry
                Change your array indicies.
                LOOP inner

        (Debug, print out the lowest members of the arrays)
        Test for overflow of highest array element, if so exit loop
        Copy your arrays as wanted.

        LOOP outer ( one complete Fib add per loop )

Print results
Exit processsing


HTH?

Steve

P.S.  Dave preempted me again, must type faster...
SRN
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 06:55:28 PM
lol Steve - i make a lot of typos, though
my loop could be modified to use the carry flag if AL was set to 0 after it was stored and use STC after SUB
i thought it was just easier to use AH - so the SUB doesn't wipe it out
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 07:04:11 PM
Ded, Sorry maybe my bad when I said "teacher wants us to add arr1 and arr2 and put result in arr3' he actually wants that but with fibonacci numbers: something like that:
0 0 0 1
0 0 0 1
0 0 0 2
-------
0 0 0 1
0 0 0 2
0 0 0 3
-------
0 0 0 2
0 0 0 3
0 0 0 5
-------
0 0 0 3
0 0 0 5
0 0 0 8
-------
0 0 0 5
0 0 0 8
0 0 1 3
-------
0 0 0 8
0 0 1 3
0 0 2 1
-------
0 0 1 3
0 0 2 1
0 0 3 4

I have to togle digits in the array I guess and go back to 72 element after each adding procedure ?For what I think is after each adding move value of arr2[di] to arr1[di] and then arr3[di] to arr2[di] and continue ?
Title: Re: Fibonacci Numbers Using Arrays
Post by: FORTRANS on November 25, 2009, 07:09:09 PM
Hi Dave,

   Yeah, if "doing it by hand" It's easier to use a variable
or register.  The subtract 10 will do bad things to the flags.
With my code it was easier to use the carry flag as AAA
does all the BCD work, so it is less confusing.  (To me at
least.)

   Hope we're doing more good than bad here.

Regards,

Steve N.
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 07:50:37 PM
a Fibonacci sequence is created when the new number is the sum of the previous two numbers
rather than copying numbers, you could just switch arrays:
1) add MyArr1 to MyArr2 and put the sum in MyArr3
2) add MyArr2 to MyArr3 and put the sum in MyArr1
3) add MyArr3 to MyArr1 and put the sum in MyArr2
repeat steps (1) through (3)
you can do this by using "base+index" addressing, then switch bases

first, though - let's make a little improvement to our basic add loop
one technique that can be used is to get rid of the CMP instruction by using SUB in its' place
if the SUB creates a carry, it means the number was less than 10 to start with, so 10 is added back on to correct it
we can combine that with Steve's use of the carry flag to make the loop more efficient

        mov     di,71           ;index to last digit
        lea     cx,[di+1]       ;calculates 72 for the loop count
        mov     dx,10           ;DL = 10, DH = 0
        xor     ax,ax           ;start with AX = 0 and XOR always clears the carry flag

add_loop:
        adc     al,MyArr1[di]   ;add carry flag to digit from value 1
        add     al,MyArr2[di]   ;add digit from value 2

        sub     al,dl           ;is it > 10 ?
        jnc     no_correction   ;yes - skip correction (carry flag = 0)

        add     al,dl           ;add the 10 back in (carry flag = 1)

no_correction:
        mov     MyArr3[di],al   ;store the result
        cmc                     ;invert (compliment) the carry flag
        dec     di              ;adjust the index - INC and DEC do not affect the carry flag
        mov     al,dh           ;zero the accumulator
        loop    add_loop        ;loop decrements CX but also does not affect the carry flag

;if CF = 1 at this point, the accumulator has overflowed

now, give me a few minutes to write the Fibonacci generator...
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 07:55:08 PM
we have to start fib sequence from 1 and 1 in arr1 and arr2 (72th digit). ded please keep it as simple as possible for me to be able to understand it....

Thanks a lot :)
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 08:15:41 PM
notice that MyArr2 should start with a value of 1, or the thing will loop forever - lol
give this a try....

        mov     bx,offset MyArr1  ;start with BX = MyArr1
        mov     bp,offset MyArr2  ;start with BP = MyArr2
        mov     si,offset MyArr3  ;start with SI = MyArr3
        mov     dx,10             ;DL = 10, DH = 0
        xor     ax,ax             ;start with AX = 0 and XOR always clears the carry flag

fibonacci_loop:
        mov     di,71             ;index to last digit
        lea     cx,[di+1]         ;calculates 72 for the loop count

add_loop:
        adc     al,[bx+di]        ;add carry flag to digit from value 1
        add     al,[bp+di]        ;add digit from value 2

        sub     al,dl             ;is it > 10 ?
        jnc     no_correction     ;yes - skip correction (carry flag = 0)

        add     al,dl             ;add the 10 back in (carry flag = 1)

no_correction:
        xchg    si,bx             ;we need SI to be in either BP or BX for base+index addressing
        mov     [bx+di],al        ;store the result
        xchg    si,bx             ;switch BX and SI back
        cmc                       ;invert (compliment) the carry flag
        dec     di                ;adjust the index - INC and DEC do not affect the carry flag
        mov     al,dh             ;zero the accumulator
        loop    add_loop          ;loop decrements CX but also does not affect the carry flag

;if CF = 1 at this point, the accumulator has overflowed

        xchg    bp,si             ;rotate the array base addresses
        xchg    bp,bx
        jnc     fibonacci_loop    ;loop until overflow occurs

;the base address of the array with the last valid result is in SI

EDIT - made a couple corrections
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 08:23:16 PM
thanks I am going to my lunch break to examine it. Will write after that :)
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 10:02:58 PM
DednDave after I examine your code on paper I have few questions.

1. If I want to set 72th element of Myarr1 and Myarr2 to 1 do I have to do that in the begining:
        mov     bx,1
        mov     bp,1
        mov     si,offset MyArr3  ;start with SI = MyArr3

2. adc  al,[bx+di] is equal to : add al,[bx+di] ; add al,carry ? if we had 5 in [bx+di] will have 6 after adc ?

3. Can we change: sub al,dl with after
add     al,[bp+di]
CMP AL,9
JA carry

4.     xchg    si,bx         
        mov     [bx+di],al        ;store the result
        xchg    si,bx

Isnt that equal to : mov [si+di],al ?

5. Printing: is that the way to print the result

Mov SI,72

print:
MOV AX, [SI]
CALL PUTDEC

dec si
cmp SI,0
JNZ print

Thanks
Title: Re: Fibonacci Numbers Using Arrays
Post by: FORTRANS on November 25, 2009, 10:51:04 PM
Hi,

Quote from: MGG on November 25, 2009, 10:02:58 PM
1. If I want to set 72th element of Myarr1 and Myarr2 to 1 do I have to do that in the begining:
        mov     bx,1
        mov     bp,1
        mov     si,offset MyArr3  ;start with SI = MyArr3

   Well, you seem to be working with the right end of the array
being the first elements?  Then something like.


        MOV     BYTE PTR [BX+71]        ; Set first element of byte array to 1

Or
MyArr1  DB      71 dup (0), 1     ; Set first element of byte array to 1


Quote
2. adc  al,[bx+di] is equal to : add al,[bx+di] ; add al,carry ? if we had 5 in [bx+di] will have 6 after adc ?

   Well that depends on what is in AL and if the carry flag is set.
If AL = zero and CF = 1 and [BX+DI] = 5, then 6 yes.
If AL = zero and CF = 0 and [BX+DI] = 5, then 5.

Quote
4.     xchg    si,bx         
        mov     [bx+di],al        ;store the result
        xchg    si,bx

Isnt that equal to : mov [si+di],al ?

   Yes, sort of.  You cannot use two index registers to
address a memory location.  (And you can't use two base
registers either.)  So Dave is using BX with the contents of
SI for the access.  So he has to swap an index register with
a base register to have a legal instruction.  (One base register
and one index register is allowed.)

Steve N.
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 25, 2009, 11:06:30 PM
1) you could use the BX or SI registers
but, the simplest way is to direct address them
Steve is right also - you could initialize the arrays that way
this way, you can put the arrays in the uninitialized data segment and make the program a little smaller

        mov byte ptr MyArr1+71,1
        mov byte ptr MyArr2+71,1

2) that depends on the carry flag
ADC is similar to ADD, but it adds another 1 if the carry flag is set
if the carry flag is clear, it is the same as ADD

3) the SUB/ADD combination i showed you is more efficient
the CMP is replaced by the SUB
the two instructions leave the carry flag in opposite states

4) if i remember correctly, you cannot use [SI+DI] in 16-bit code - i could be wrong, there
i thought one of the registers had to be BX or BP and the other had to be SI or DI
i may be wrong - try it - the assembler will spit out an error if the register combination is illegal
just a note: if you use BP by itself ( [BP] ), it is referenced to the SS stack segment
if you use BP with SI or DI ( [BP+DI] ), it is referenced to the DS data segment

5) PUTDEC would be slow - faster to print the whole string at once
write a loop to convert the final value to ASCII numeric characters
then, use PUTSTRNG with CX = 72
as you recall, SI holds the address of the final value
i think PUTSTRNG uses DX, so.....

        mov     dx,si               ;save the address in DX for PUTSTRNG
        mov     al,30h              ;ASCII "0"
        mov     cx,72

ascii_loop:
        or      [si],al
        inc     si
        loop    ascii_loop

        mov     cx,72
        call    PUTSTRNG

Steve beat me, that time - lol
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 25, 2009, 11:36:50 PM
Steve, dedndave my level of programming cant handle more efficient code I need more understandable code for me. CMP AL,9 looks more clear in my eyes. and Putdec is well known command. I tried using your methods and program to generate the 72th fibonacci number which CX should point to (the 72th Fibo number). It should be(49845 40118 79264). I can not get to that result and since I dont understand many of the procedures I can not see/fix what the problem is. I tried using ascii it prints $#!@$ instead of number. with putdec it prints number but not any of those. If I change CX to 8 it should print - 21 instead it prints zero ...  It is all good and efficient with all the carry's and and moving through the indexes but cant make it work that way :((

72 (15 digits) :
49845 40118 79264
8 (2 digits) :
21
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 26, 2009, 12:13:24 AM
ohhhhhhhhhhhhhhhhh - lol
i wrote the loop so it would generate numbers until it overflows
i did not know you wanted the 72nd one - lol
so - if you set MyArr1 = 1 and MyArr2 = 1, MyArr3 on the first pass would be the first one ? or the third one ?
usually, i see it starting at 0,1,1,2,3,5,8,13,21.......
if the answer is only 15 digits long, why are we adding 72 digit numbers ? - lol
give me a little time - let me write a program for it.....
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 26, 2009, 12:19:43 AM
I did set CX static just to make the program work. CX will change from the input KBD.... User will ask for 22nd fibbo number and program has to generate and print that number on the screen. Program has to overflow if number goes over 72 digit ... and to generate message for it.. 

in fact we can calculate if arr1[bx] + arr2[bx] = 0 to stop and to print... but I  am not looking for speed just to work so if it adds zeroes it doesnt mather to me :) speed is not issue here working is issue :P

first numbers should be 1 and 1 in myarr1 and myarr2. the user will input number like : 22 ... it will go to CX throug getdec. and means user wanth 22nd fibonacci number. and the program has to show him: 22nd Fibo number ... in the way teacher set 1 1 first number should be 2 ... I guess ... I was looking that one for reference : http://www.fullbooks.com/The-Fibonacci-Number-Series1.html

He wants us to tell him what will be the max fibonacci number we can input in 72 digit without overflow. In the website is says 346th fibo number displays in 72 digit and 347th overflow ...
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 26, 2009, 12:34:46 AM
ok - lemme play with it a little bit.....
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 26, 2009, 12:37:41 AM
found that calculator. It works like the previous website + 1
http://www.calcresult.com/maths/Sequences/expanded_fibonacci.html
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 26, 2009, 12:40:01 AM
do you want to generate a list like that ?
or just the one value ?
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 26, 2009, 12:42:47 AM
just one value the last one in Arr3 ...Teacher said user should try different numbers as input til program say: overflow occured. please try smaller number. pleaseeee as simple as possible no fancy jumps through the indexes and registers :)
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 26, 2009, 12:45:36 AM
i found a boo-boo - lol
i thought that [BP+DI] used the DS segment
i was wrong - lol - it uses the SS segment
it has been a while since i wrote any 16-bit base index code - sorry about that
that line has to be changed...

        add     al,ds:[bp+di]     ;add digit from value 2
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 26, 2009, 12:49:51 AM
it should be like:

CX = some number from KBD
Loop CX

loop DI
for DI=72 to 0 do
Arr3 = arr1 + arr2 + carry  ----> somehow have to move values from arr2 to arr1 and arr3 to arr2 to work for fibonacci ...

if arr3>9

arr3=arr3-10
carry=1
DI=DI-1
else
carry = 0
Di=di-1


SHould be something like that
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 26, 2009, 12:51:24 AM

        mov     ax,@DATA
        mov     ds,ax
        mov     es,ax
        mov     bx,offset MyArr1  ;start with BX = MyArr1
        mov     bp,offset MyArr2  ;start with BP = MyArr2
        mov     si,offset MyArr3  ;start with SI = MyArr3
        mov     dx,10             ;DL = 10, DH = 0

        mov     cx,72             ;<------------------------------- put the fibonacci number you want in CX

fibonacci_loop:
        push    cx                ;save the loop count
        mov     di,71             ;index to last digit
        lea     cx,[di+1]         ;calculates 72 for the loop count
        xor     ax,ax             ;start with AX = 0 and XOR always clears the carry flag

add_loop:
        adc     al,[bx+di]        ;add carry flag to digit from value 1
        add     al,ds:[bp+di]        ;add digit from value 2

        sub     al,dl             ;is it > 10 ?
        jnc     no_correction     ;yes - skip correction (carry flag = 0)

        add     al,dl             ;add the 10 back in (carry flag = 1)

no_correction:
        xchg    si,bx             ;we need SI to be in either BP or BX for base+index addressing
        mov     [bx+di],al        ;store the result
        xchg    si,bx             ;switch BX and SI back
        cmc                       ;invert (compliment) the carry flag
        dec     di                ;adjust the index - INC and DEC do not affect the carry flag
        mov     al,dh             ;zero the accumulator
        loop    add_loop          ;loop decrements CX but also does not affect the carry flag

;if CF = 1 at this point, the accumulator has overflowed

        xchg    bp,si             ;rotate the array base addresses
        xchg    bp,bx
        pop     cx                ;recall the loop count
        jc      loop_overflow

        loop    fibonacci_loop    ;loop until overflow occurs

;the base address of the array with the last valid result is in SI

loop_overflow:

add the ascii loop and PUTSTRNG here
the array address is in SI
with a little work, we can get rid of the leading 0's
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 26, 2009, 01:01:32 AM
add this code to the end of the code above
it will get rid of leading zeros
i found out that PUTSTRNG wants the address in DI - not in DX
notice in the code above, the ES register is set to @DATA, as well as DS

loop_overflow:
        mov     di,si               ;save the address in DI for PUTSTRNG
        mov     al,30h              ;ASCII "0"
        mov     cx,72

ascii_loop:
        or      [si],al
        inc     si
        loop    ascii_loop

        cld
        mov     cx,71
        repz    scasb
        dec     di
        inc     cx
        call    PUTSTRNG
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 26, 2009, 01:08:00 AM
yeah it works now :) just take attention from 344 to 346 .. after 344 number doesnt change. I believe after CX = 346 it shouldnt work and have to display msg. 346 is the max number to display in 72 digit. 347 need 73 digits.

Now I am going to class thanks :) will examine it tonite ..
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 29, 2009, 02:19:20 AM
Hi dedndave I was playing with the program on ThanksGiving and can not make it work with 345 and 346 the overflow should be on 347.. if I remove the JC it displays normally the 345th and 346th. I fixed some of the code you gave me because it didnt display first 5 numbers. I believe it was something small in CX. here is the code which overflow at 345 instead of 347. can you take a look? Thanks

;===================================================================
   INCLUDE PCMAC.INC       
     .MODEL  small,basic
      .586
      .STACK 100
   
;===================================================================
                                       ;PROCEDURES TO
             
     
      EXTRN   CLEAR:FAR     ;CLEAR SCREEN
      EXTRN   NEWLINE:FAR    ;DISPLAY NEWLINE CHARACTER
      EXTRN   GETDEC$:FAR     ;GET 16-BIT DECIMAL FROM KBD
      EXTRN   PUTDEC$:FAR     ;DISPLAY 16-BIT DECIMAL INT
      EXTRN   GETDEC:FAR
      EXTRN   PUTDEC:FAR
      EXTRN   PUTSTRNG:FAR   ;DISPLAY CHARACTER STRING

   
;===================================================================
;DATA  S E G M E N T   D E F I N I T I O N
;
      .DATA
MyArr1   DB 71 dup (0),1
MyArr2   DB 71 dup (0),1
MyArr3   DB 72 dup (0)
Carry    DB  0
   
         
.CONST
SPACES DB ' '
over   DB 'overflow occured please go one step backward'
;===================================================================
;C O D E   S E G M E N T   D E F I N I T I O N
;
            .CODE
       ASSUME  DS:DGROUP
;===================================================================
MAIN PROC

        MOV     AX,DGROUP ;SET DS-REGISTER TO POINT TO
        MOV     DS,AX        ;CONSTANT DATA SEGMENT
        MOV     ES,AX      ;SET ES-REGISTER
        CALL    CLEAR


        mov     bx,offset MyArr1  ;start with BX = MyArr1
        mov     bp,offset MyArr2  ;start with BP = MyArr2
        mov     si,offset MyArr3  ;start with SI = MyArr3
        mov     dx,10             ;DL = 10, DH = 0

        CALL getDEC
   mov     cx,AX             ;<------------------------------- put the fibonacci number you want in CX

fibonacci_loop:
        push    cx                ;save the loop count
        mov     di,71             ;index to last digit
        lea     cx,[di+1]         ;calculates 72 for the loop count
        xor     ax,ax             ;start with AX = 0 and XOR always clears the carry flag

add_loop:
        adc     al,[bx+di]        ;add carry flag to digit from value 1
        add     al,ds:[bp+di]        ;add digit from value 2

        sub     al,dl             ;is it > 10 ?
        jnc     no_correction     ;yes - skip correction (carry flag = 0)

        add     al,dl             ;add the 10 back in (carry flag = 1)

no_correction:
        xchg    si,bx             ;we need SI to be in either BP or BX for base+index addressing
        mov     [bx+di],al        ;store the result
        xchg    si,bx             ;switch BX and SI back
        cmc                       ;invert (compliment) the carry flag
        dec     di                ;adjust the index - INC and DEC do not affect the carry flag
        mov     al,dh             ;zero the accumulator
        loop    add_loop          ;loop decrements CX but also does not affect the carry flag

;if CF = 1 at this point, the accumulator has overflowed

   jc      loop_overflow


        xchg    bp,si             ;rotate the array base addresses
        xchg    bp,bx
        pop     cx                ;recall the loop count
        loop    fibonacci_loop    ;loop until overflow occurs

   
   jmp print
;the base address of the array with the last valid result is in SI

loop_overflow:
   LEA DI,OFFSET over
   MOV cx,sizeof over
   call putstrng
   jmp endd       
   
print:

   mov     di,si               ;save the address in DI for PUTSTRNG
        mov     al,30h              ;ASCII "0"
        mov     cx,72

ascii_loop:
        or      [si],al
        inc     si
        loop    ascii_loop

        cld
        mov     cx,72
        repz    scasb
        dec     di
        inc     cx
        call    PUTSTRNG




ENDD:   

   

.EXIT
MAIN ENDP                       
        END    MAIN
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 29, 2009, 04:12:48 AM
the reason that happens is this...
the overflow is detected before we allow it to happen in the [SI] array
that way, the array pointed to in SI is always valid
the array that actually is overflowed is pointed to in BX
also - remember, your teacher is counting the Fibonacci numbers off by 1
what he is calling Fibonacci #8 is actually Fibonacci #9
if you go to the web-based calculator site and crank out the 72 digit number, we have it right

one way to fix the problem is to add an extra element to all the arrays
when we get to the end, if the first element of the [SI] array is not 0, it overflowed
i don't know if that is acceptable to you, as we are now using 73 element arrays instead of 72
however, it could be explained that the 73rd element is the "carry" or "overflow" element and not part of the value

another way to fix it would be to set a flag the first time carry is set and allow the loop to make one more pass
that is clumsy and silly, really, as we are forcing it to give us an invalid number
in the end, we won't display that number, anyway - we will just display an "Overflow" message in it's place
this still may be the best solution, as we are using 72 byte arrays which meet his criteria

EDIT - i think i have a better solution
we can simply use the array in [BX] instead of the one in [SI] and adjust our count number so they match the teachers
i will play with it tomorrow and see if it flies
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on November 29, 2009, 02:30:42 PM
here we go - give this a try....
Title: Re: Fibonacci Numbers Using Arrays
Post by: raymond on November 30, 2009, 03:32:06 AM
One thing I would like to know is why your teacher is insisting that you use three arrays. Computing Fibonacci numbers is so much easier using only two arrays. Is it possible to ask him that question and post his reply?
Title: Re: Fibonacci Numbers Using Arrays
Post by: ilian007 on November 30, 2009, 03:34:33 AM
I will ask him tomorrow and will anser your quest raymond
Title: Re: Fibonacci Numbers Using Arrays
Post by: FORTRANS on February 19, 2010, 05:41:37 PM
   This is something of an insomnia induced rant.  If you are a
person looking for "real" content, bail out now.  You have been
warned.  Those that like blither carry on.

   Here is a version of a Fibonacci number program that uses an
AAA instruction to correct the unpacked BCD number.  In reply 1
I showed some code using the carry flag and an ADC to propagate
the carries along.  Dave in reply 5 showed that a different way
that uses the AH register to propagate a carry was possible.  I
think that until Dave pointed to that I just considered this to
be something to work around.  It changes AH so you can't use it
for something else.  But as that was intentional, you should be
able to use that effect productively.  This idea popped into my
so called mind after I woke up in the middle of the night.  And
it wouldn't leave me until I worked it out and coded it up.  As
I have not seen it used this way before (or do not remember any
such examples) I thought I would post it.

   After coding it up, I do not see any real advantage over the
way I did it before.  I did find it interesting to play with an
X86 instruction that RISC aficionados probably sneer at.  In my
program I used the three arrays that the other programs in this
thread use to ease any comparison wanted.  To address Raymond's
comments in reply 36, I think that when teaching beginners that
using two source arrays with a distinct destination array would
make it easier to describe the Fibonacci sequence and a program
to generate it, rather than using a two array program to do the
same thing.  Once the ideas settle in, it is better to use only
two arrays, change pointers to the arrays, and overwrite one of
the arrays with the result.  It obviates the need for a routine
to copy the arrays before the next iteration and saves space as
well.  But I think teaching rank beginners those concepts would
be more difficult.  Of course then my incrementing digits in an
ASCII label to create a loop counter would not be productive in
such an environment.  Oopsie.

   End rant.

Cheers,

Steve N.
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on February 19, 2010, 08:24:15 PM
well, Steve, if it makes you feel any better, i wouldn't use "arrays" (BCD strings) at all
i would use multi-byte binary integers   :bg
it would greatly simplify the loop and the carry flag would wrap around nicely
as for using 2 registers instead of 3 - it would be easier to use 2, especially with multi-byte integers
i think we all were trying to follow the students example, in order to satisfy the instructor
we have done the same thing on several threads in the 16-bit sub-forum
i was interested in teaching the students 2 basic things
1) how to approach problems using assembler
2) how to write code that others can read - lol
Title: Re: Fibonacci Numbers Using Arrays
Post by: FORTRANS on February 19, 2010, 09:41:38 PM
Hi Dave,

   Right, I used BCD and the three arrays only as an illustration.
And it would have been pointless to play with AAA without them.
The discussion of how to teach to beginners was one point I
wanted to make.  That programming is fun, even if it keeps
you from sleeping was another.  I tried to show two ways to
solve the problem and the advantages of each.  Is my code
unreadable?  That was not the intent.

Regards,

Steve N.
Title: Re: Fibonacci Numbers Using Arrays
Post by: dedndave on February 19, 2010, 09:47:53 PM
QuoteIs my code unreadable?

:bg  not your code, Steve - their code
i forget which student it was, but i had to edit the whole file just to understand what they were trying to do
if they didn't take anything else away, i hope it was neat code - lol
Title: Re: Fibonacci Numbers Using Arrays
Post by: FORTRANS on February 19, 2010, 10:11:22 PM
Hi,

   Ah indeed, their code often leaves me surprised.  That is
one of the best thing to teach and not always emphasised.
I try to look at my code after a few days just to see if I
glossed over something that will fade from memory if not
commented.  Some code I wrote would be easier to rewrite
than for me to try and figure out.  Oh well.

Best regards,

Steve