Many Euler problems involve huge numbers which are a hastle in 16-bit, so I was pleased to work out a way using decimals instead.
The programme has solved something, and now we need to count the successes... so...
mov bl,a decimals always involve dividing by ten
mov si,f7 point to a convenient space. I usually use the PSP
& inc byte ptr[si] add to the total
cmp [si],bl is it ten?
jnz ??? no, go back to the main programme
mov [si],bh yes, make the digit zero (BH=0)
dec si and move to next digit
jmp &
it will keep going...to a nine digit number in my solution a variation of PE #92
well - there are a number of alternatives
however, BCD math is good for some Euler problems
1) write 32-bit programs
2) use 32-bit registers in 16-bit programs
3) use the FPU, which can handle several BCD digits
How can I use 32-bit registers in 16-bit? Use machine code maybe? Where can I get the machine code hex from? ie, is PUSH EAX the same as PUSH AX?
What difference would BCD make to the lines? Save a few bytes of memory maybe, but makes it much harder to extract to display?
Although I know the Intel definitions for AAA, AAM, AAS and AAM, I still don't know what they actually do!
this should allow the use of 32-bit registers:
.MODEL Small
.STACK 1024
.DOSSEG
.386
once you do that, you can use either PUSH AX or PUSH EAX
as for BCD or "packed decimal", it is actually easier to convert to ASCII strings
although, it is not the most efficient code when multiplying or dividing
the FPU can perform BCD math for you
have a look at Ray's tutorial...
http://www.ray.masmcode.com/BCDtut.html
http://www.ray.masmcode.com/
Hi,
AAA, AAD, AAM, and AAS are instructios to operate on unpacked
BCD operands. The following text may help? And I wrote a
program to use AAA in the following thread. Rather blunt, but
should be easy to decipher.
http://www.masm32.com/board/index.php?topic=12771.30
HTH,
Steve N.
"AAA","ASCII Adjust after Addition:
Adjusts the result in AL, after two unpacked
BCD digits have been added together. If AL > 9, AL is adjusted
to the proper BCD digit (AL - 10), AH is incremented, and the
Carry and Aux Carry flags are set. If AL < 10, AL and AH are
unaffected, and the Carry and Aux Carry flags are cleared.
SAMPLE CODE
MOV AH,07
MOV AL,08
ADD AL,AH ;15D IN AL
SUB AH,AH ;AH=0
AAA
OR AX,3030 ;Convert digits to ASCII","? ? ? B ? M"@
"AAA+","AAA continued.
His example can be bad. AAA uses the CY and AC flags set
by the ADD to make the correction. My code was.
ADD AL,[DI] ; If there is any existing data.
XOR AH,AH
AAA ; Adjust after addition.
And that produced the wrong result. Note that AH must be
zeroed as AAA increments AH contents, rather than setting AH
to zero or one. The working code is now.
XOR AH,AH ; Needed as AAA increments AH contents.
ADD AL,[DI] ; If there is any existing data.
AAA ; ASCII Adjust after Addition.
bytes 8088 186 286 386 486 Pentium
1 8 8 3 4 3 3 NP",""@
"AAD","ASCII Adjust before Division:
Converts unpacked BCD digits in AH and AL
to a single binary value in preparation for the DIV
instruction. AL is set to 10*AH + AL. AH is cleared.
SAMPLE CODE
MOV AH,'7'
MOV AL,'6'
AND AX,0F0FH ; Convert ASCII to BCD 0706
AAD ; Convert to 004C
bytes 8088 186 286 386 486 Pentium
2 60 15 14 19 14 10 NP
(second byte is multiplier)","? M M ? M ?"@
"AAM","ASCII Adjust after Multiply:
Adjusts the results in AX after two unpacked
BCD digits have been multiplied together. Doesn't have to
be used only after multiplication. Reverses what AAD does.
AL is divided by 10 leaving the quotient (MSD) in AH and
the remainder (LSD) in AL. (Opposite of DIV Byte.)
SAMPLE CODE
MOV AX,004C; AX=76 DEC
AAM ; NOW = 0706h
OR AX,3030 ; NOW = 3736h
bytes 8088 186 286 386 486 Pentium
2 83 19 16 17 15 18 NP
(second byte is divisor)","? M M ? M ?"@
"AAS","ASCII Adjust after Subtraction:
Adjusts the results in AX after a subtraction.
If the BCD subtraction caused a decimal carry, AAS adjusts AL,
decrements AH, and sets the Carry and the Aux Carry flags.
Else AL and AH are unaffected, and the two flags are cleared.
SAMPLE CODE
MOV AH,01 ; AH=BCD 1
MOV AL,04 ; AL=BCD 4
MOV BL,07
SUB AL,BL ; AL <-AL-BL (14-7)
AAS ; AX=0007 BCD
OR AX 3030; ASCII 3037
bytes 8088 186 286 386 486 Pentium
1 8 7 3 4 3 3 NP","? ? ? B ? M"@
oops - forgot DAA, DAS :P
nice tutorial, though :U
Quote from: dedndave on January 24, 2012, 04:35:05 PM
oops - forgot DAA, DAS :P
Hi,
Well, he asked for the upacked BCD guys. But look below.
Quote
nice tutorial, though :U
Thanks,
Steve
"DAA","Decimal Adjust after Addition:
Adjusts the sum in AL, after two packed BCD values
have been added. Converts the sum to two packed BCD
digits in AL. The Carry flag is set if a carry occured.
bytes 8088 186 286 386 486 Pentium
1 4 4 3 4 2 3 NP","? M M B M B"@
"DAS","Decimal Adjust after Subtraction:
Converts the result of subtracting two packed BCD
operands in AL to two valid packed BCD digits. The
Carry flag is set if a borrow was needed. Packed BCD
(Binary Coded Decimal) consists of a valid decimal
digit in each half byte of the byte operand.
bytes 8088 186 286 386 486 Pentium
1 4 4 3 4 2 3 NP","? M M B M B"@