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.
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...
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.
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.
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.