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
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
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 ...
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
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 ..
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
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)
Ded, yeah by what I see I guess it is unpacked BCD. I will do a little bit more research
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....
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
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
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
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 ?
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.
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...
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 :)
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
thanks I am going to my lunch break to examine it. Will write after that :)
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
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.
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
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
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.....
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 ...
ok - lemme play with it a little bit.....
found that calculator. It works like the previous website + 1
http://www.calcresult.com/maths/Sequences/expanded_fibonacci.html
do you want to generate a list like that ?
or just the one value ?
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 :)
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
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
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
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
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 ..
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
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
here we go - give this a try....
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?
I will ask him tomorrow and will anser your quest raymond
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.
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
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.
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
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