It actually adds it correctly w/ the the carry ... but now I have extra '0's on the left of the number
At some point, you had determined the number of characters in the decimal and integer portions in order to "equilibrate" your two numbers. You now know how many decimal and integer digits to process. Use those numbers in ECX to control your loops, and you won't get those extra 0's.
hmmm... actually I get an error of memory could not be written if I enter a whole number alone, like: '2' and '5'
When you parse such an input, insert a decimal point yourself to "equilibrate" it with the other input.

If neither string would have a decimal point, the maximum count of decimal digits would then be 0. If you detect this case when you start the addition, you could even skip inserting a decimal point in the answer.

As you can see, the style of answer returned is entirely up to you. (You could even include options to let the user decide on the style; but I would suggest you wait a little while for this:tongue: .)

Raymond
Posted on 2003-04-26 08:32:19 by Raymond
I don't quite understand what you just said...
Posted on 2003-04-26 15:54:32 by locke
Im not too understand, This is my understanding.

Eax is DWORD, so.....
it splitted into 2 section, first 2 byte (it is al and ah) is the comma or fraction and the rest is the real value.

If I put a value 3.14 on eax then eax now have value 0x0003-000E. The last 2 byte is Signed and the first 2 byte is unsigned. So Fraction value can hold up to 32000 and the last byte is limited to 32000. Correct me if Im wrong.
Posted on 2003-04-26 19:54:47 by realvampire

As V Coder explained, go directly from adding the decimals to adding the integers.

HOWEVER, as you exit Loop1, you must save the flags because the carry flag will be affected by your setPointer macro instructions. You then retrieve the flags just before entering the L2 loop.

Raymond


Hey Raymond, thanks for noticing that. Yes, the macros (which I treated mentally as pure mov instructions) would definitely affect the carry...

I had written pushf and popf to store and retrieve the flags, but commented them out as follows:

;pushf ***** - should not be necessary because none of the ;following instructions affect the carry
Addition2:
...
setPointer esi,FPVal_W1
setPointer edi,FPVal_W2
setPointer ebx,FPSum_W1

;***** dec ebx - leave out this I think

mov ecx, lengthof FPVal_W1
;***** clc - leave out the clc because you are simply using the ;carry flag from the last addition
;popf ***** - should not be necessary because none of the ;preceding instructions affect the carry

As you said, the pushf and popf were necessary. Didn't notice that - a result of the time I posted (and the fact that I am now learning Win32 and MASM is way beyond me...

(Plus, that you can notice a fault in my code means you're realllllllllll good.) :)
Posted on 2003-04-26 22:26:49 by V Coder

For your add routine to work, you need to "right justify" your whole number part. Don't change the fraction part.

Store it as

00000000000xxx

rather than as

xxx00000000000

This way you also get zeros in the correct places. Then for printing, you just need to skip over zeros on the correct ends of the two strings.


This is what I am thinking....

I pointed this out in a different thread you had started...

I will look over your code tonight, and see where I can help fixing it....
Posted on 2003-04-26 22:30:34 by V Coder
locke

When you processed the input strings, you had to count the number of integer and decimal digits in each string and keep those values in memory so that you could later compare them and choose the higher values in order to "equilibrate" your strings.

You should use those higher values to load ECX for the addition loops instead of the "lengthof" of the variable buffers to avoid the endless 0's.

As for your other problem, when you want to count the number of integer and decimal digits in the user input, you have to check where the decimal point is located. If you don't find one before the terminating 0, you simply assume that one was there and put a 0 in the memory variable for the count of decimal digits in that string, skipping the actual count.

Is there anything else to be clarified?

realvampire:

There are ways to represent decimal values in a fixed point "integer" format and do "integer" type math operations on such values. However, it is not done as per your example. If you are seriously interested in that subject, there is a library of functions for using fixed point decimals available on Hutch's site, with commented source files.

Raymond
Posted on 2003-04-26 22:45:45 by Raymond
well on the topic of the AAA and AAM etc these opcodes will become unsuporrted by the new 64bit cpus(out of 32bit mode of cource) so i suggest if you plan on using this in the future to find a nother way perhaps?
Posted on 2003-04-26 22:55:46 by Qages

It actually adds it correctly w/ the the carry ... but now I have extra '0's on the left of the number

So if I add '900.999' and '100.111' I get: '0000000000000000001001.110'
You must make a distinction between the entire buffer and the "significant" part of it. You get the extra zeros on the left because you told the print routine to display the digits starting with the first digit in the buffer. You probably want to "delete" the extra zero digits. The easiest way is to simply search for the first non-'0' character. Then instead of telling the print routine to print from the beginning, tell it to start printing from that first non-'0' character.
Posted on 2003-04-27 00:33:15 by tenkey
locke

You may want to study the attached text file (primarily a parsing algo for your assignment) as an example of how to approach a programming problem in a detailed systematic manner to cover most of the possibilities and take appropriate action.

Some purists may find more efficient (and maybe more obscure) code, but the main intent is to get you started on a better base. Assembler programming is a lot of fun but you have to pay very close attention to a lot of the fine details which may be handled in a transparent manner (sometimes very inefficiently) by HLL's.

Raymond
Posted on 2003-04-27 20:08:19 by Raymond
Just to explain my knee-jerk reaction to the "ASCII OPERATIONS AAA" expression in a previous post of mine, the AAA instruction really works only with the lower 4 bits of the byte in AL and the AF (auxilliary flag), the upper 4 bits of AL being simply disregarded. You then have to convert the resulting 4-bit binary result in AL (always between 0 and 9) where the upper 4 bits have been re-zeroed. If you add 30h to it, you get an ascii decimal digit.

Therefore, you could add characters other than the decimal digits and still get some "valid" result. And, if you add something else than 30h, you can get surprises.

As an example for those who may want to play with those principles, if you add the digits in " wars" with the digits in " +CIA", you can get "AHEAD" if you add 40h to the output of the AAA instruction. (If you add 60h instead, you would get the same result in lower case letters.)

For skeptics, try the following code:
    .486

.model flat, stdcall
option casemap :none ; case sensitive

; #########################################################################

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

; #########################################################################

.data
str1 db " wars"
str2 db " +CIA"
result db 8 dup(0)

.code

start:
mov esi,offset str1+4
mov edi,offset str2+4
mov ebx,offset result+7

mov ecx,5
clc
@@:
mov al,[esi]
adc al,[edi]
aaa
pushfd
or al,40h
dec ebx
mov [ebx],al
dec esi
dec edi
popfd
loop @B

invoke MessageBox,0,ebx,ADDR str1,MB_OK
invoke ExitProcess,0

; #########################################################################

end start
Posted on 2003-04-28 12:49:39 by Raymond
I have a similar function for adding 2 floating point ascii (without any limits) but I can't seem to find it on my HD. I'll post something if I find it.

this is just on top of my head(so I might be wrong) on replacing AAA instruction (a problem on 64 bit cpus? pointed by Quages - I don't know about rotate and bt* instructions if these instructions are going to be supported by 64-b cpu's.)

This is an emulation of AAA(only AF and CF are affected here)
pushad

pop ecx
and al, 0Fh
cmp al, 9
ja _a9
ror ecx, 5
jnc _afns

_a9:

add al, 6
inc ah

rol ecx, 5
bts ecx, 4
bts ecx, 0 ;tricky code - dunno if this works... CF = ecx[0] ... CF = 1 :)

jmp _x

_afns:

rol ecx, 5
and ecx, 0FFFFFFEEh

_x:
push ecx
popfd
I think you can make this work on 1 register only. ;)

Off topic: I believe you can do this fairly nice with MMX(this whole floating point ascii addition thingy.). Just a thought.
Posted on 2003-04-28 13:31:26 by arkane