News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Hint On Decimal Multiplication

Started by devilhorse, October 29, 2008, 11:15:56 PM

Previous topic - Next topic

devilhorse

I am hoping someone can point me in the right direction on how to get the following procedure to work correctly.

GENERIC_MULTIPLY Proc InParam_1:DWord, InParam_2:DWord, szResult:DWord
Local locInParam_1:Real10
Local locInParam_2:Real10
Local locResult:Real4

Invoke FpuAtoFL, InParam_1, Addr locInParam_1, DEST_MEM
Fld locInParam_1
;Fld St(0)
Invoke FpuAtoFL, InParam_2, Addr locInParam_2, DEST_MEM
Fld locInParam_2
;Fld St(1)
Fmul

Fst locResult

Invoke FpuFLtoA, Addr locResult, 2, szResult, SRC1_FPU Or SRC2_DIMM
Finit

   Ret
GENERIC_MULTIPLY EndP

When I calculate 100.5 times 4 - the return value is correct.
However, when I calculate 100.5 times 4.0 the return is 0.00 . Whenever Ii try to calculate two numbers that each contain a decimal point, the function returns 0.00. I just need someone to give me ahint on what I am doing wrong. I will use that hint to Google, read assembly programming ebooks and search forums for the answer. I don't mind searching. i just need to be pointed in the right direction. Thanks in advance.

MichaelW

It works correctly for me.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\fpu.inc
    includelib \masm32\lib\fpu.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      result db 30 dup(0)
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
GENERIC_MULTIPLY Proc InParam_1:DWord, InParam_2:DWord, szResult:DWord
    Local locInParam_1:Real10
    Local locInParam_2:Real10
    Local locResult:Real4

    Invoke FpuAtoFL, InParam_1, Addr locInParam_1, DEST_MEM
    Fld locInParam_1
    ;Fld St(0)
    Invoke FpuAtoFL, InParam_2, Addr locInParam_2, DEST_MEM
    Fld locInParam_2
    ;Fld St(1)
    Fmul

    Fst locResult

    Invoke FpuFLtoA, Addr locResult, 2, szResult, SRC1_FPU Or SRC2_DIMM
    Finit

    Ret
GENERIC_MULTIPLY EndP
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
  @@:
    mov esi, input("in1: ")
    mov edi, input("in2: ")
    invoke GENERIC_MULTIPLY, esi, edi, ADDR result
    print ADDR result,13,10
    invoke szCmp, ADDR result, chr$("ERROR")
    test eax, eax
    jz @B
    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


in1: 100.5
in2: 4
402.00
in1: 100.5
in2: 4.0
402.00
in1:
in2:
ERROR
Press any key to exit...


eschew obfuscation

GregL

Yes, your procedure works. How are you calling it?

I would suggest you change the finit at the end of your procedure to fstp st(0). Either one clears the FPU stack, but a finit is overkill.




raymond

devilhorse
If you try to multiply 100.5 by 4.07 under the identical conditions you used for multiplying by 4.0, your result may shed some light on what may be happening. The 0.00 result you reported should be expected only IF you multiply by 0.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

jj2007

Michael's code works fine for me, too. Is your problem always reproducible? Can you post the full source?
You might try to put the finit below Local locResult:Real4.