Is it impossible in masm to assing a value to a local variable as a floating point type?

i mean this:

fpu_test proc
local Var1:real4

mov Var1, 2.48R <--- Its not addmited by masm
fld Var1

fpu_test endp

I thought masm would convert the data to a 32 bit float type and then generate code
to load data to Var1 in the form of a 32 bit single precision type.
This not happen if we create a global variable i mean:
Var1 real4 2.48R

does it mean that i have to create only global variables for "dot numbers"?

thanks
Posted on 2002-12-23 13:23:21 by IrOn
when in doubt use hex. ;)

2.48 == 401eb852h

here's some c code for you to compile. This will help you convert the floating point value to hex
[size=9]#include <stdio.h>


int main()
{
float fval = 2.48f;
printf("%08x \n", *((int*)&fval));

//test the hex value

_asm
{
mov fval, 401eb852h
}
printf("%f\n", fval);
return 0;
}


[b]EDIT POST: Much better[/b] :grin:

//float2hex.c
//
//cl /G3 /MD /c float2hex.c
//link /subsystem:console float2hex.obj

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
float f;
if(!argv[1]) return 1;
f = (float)atof(argv[1]);
printf("%08x\n", *((int*)&f) );
return 0;
}
[/size]
:grin:
Posted on 2002-12-23 14:32:59 by stryker
Probably easier to understand if you are going to use the FPU anyway since you need FP variables, and you cannot (or do not want to) use global variables:

local var1:real4
local var2:dword

lea eax,var1
mov dword ptr ,248
mov var2,100
fild dword ptr
fidiv var2
fstp var1


You can change the '248' and the divisor to suit your needs. At least, this lets you see clearly which value gets into var1.

Raymond
Posted on 2002-12-23 19:00:32 by Raymond
Personally I don't like the REAL4/8/10 notation. I always used D/QWORD or TBYTE. eg
fpu_test proc

local Var1:DWORD,Var2:QWORD

mov Var1, 2.48f
fld Var1

mov Var2, 2.48f
fld Var2

fpu_test endp

That should work with or without the f (If I remember correctly). Personally I never heard of following a floating point number with an R, perhaps thats the problem.

Raymond, while there's technicially nothing wrong with your method, it is undenibly slow and bloated :( . If only for the sake of legiable code it'd be hard to justify. But thats just my own personal feelings :) .
Posted on 2002-12-23 19:38:16 by Eóin
Eoin

I just tried a MOV VAR,2.48 with MASM32, with or without an endinf 'f'. It just returns an error message that floats and bcd's are not allowed in such an instruction. Which assembler are YOU using????

Raymond
Posted on 2002-12-23 23:22:36 by Raymond
Yep you're right, I'm sorry :( . I've gotten so used to Fasm recently I'd forgotten about that silly limitation in Masm. So my new recommendation ( :grin: ) is to follow Stryker, or use bitRAKEs fpc macro:
Posted on 2002-12-24 09:17:14 by Eóin
Eoin,

Firstly:
I was just wondering if your suggested macro would be that much faster than my "slow and bloated" suggestion??? Furthermore, when you try to read the disassembled code where the entire Macro gets inserted every time it gets used, would it also be much easier to understand than my "bloated" suggestion???

Secondly:
Any number loaded to the FPU first gets converted to a REAL10. Your Macro does not seem to retain the target value in memory. What would be the purpose of making a choice between a REAL4 or a REAL8 converted value to load to the FPU in such case????

Raymond
Posted on 2002-12-24 15:12:43 by Raymond
Raymond:

I haven't really touched on FP much, but concerning macros: think of them kind of as 'cut and paste'. What they do to your code is done pre-compile, and so the decompile of it shows nothing but the end result of the macro (cuts your macro lines out and pastes the result). While a macro would no doubt increased compile time, the program itself would run just dandy :)
Posted on 2002-12-24 16:42:35 by Miko
Raymond, I sense a certain anger towards me, I probably offended you calling your method "slow and bloated", I'm sorry. Its just that in asm we usually aim for the best approach always so I felt this silly urge to express my opinions on your method. Ignore them if they caused offense. :)

As for the macro (again it's bitRAKEs he deserves all credit) it works by creating a global variable in a const segment. For example the following two snippets would be identical (except for their segments perhaps but I never fully understood segments so I can't say)

.data

Twenty REAL4 20.0
TwoPt5 REAL8 2.5
OnePt5 REAL4 1.5

.code
fld Twenty
fld TwoPt5
fld OnePt5


.code
fld fpc(20)
fld fpc(REAL8 2.5)
fld fpc(1.5)
The reason for using REAL4/8 as opposed to REAL10 is both a size and speed issue.
Posted on 2002-12-24 17:40:30 by Eóin
Miko,

I know pretty well what macros can do. However, when a macro starts looking like a complex procedure and requires too many lines of code, my preference is to write it as a procedure, or a function, or even preferably as a simple routine if I don't think it may be reusable. (I HATE TYPING FOR NOTHING!!!)

Maybe this reflects my old schooling when writing in assembler was for highest speed AND smallest size. When large macros are called often in a program, it simply bloats it as compared to a call. (If it's a matter of the 'call' overhead, then all procedures and functions should be written as macros.)

Eoin,

No anger whatsoever. Sorry if it may have sounded as such. I was only surprised that you would call 5 lines of code "slow and bloated" but suggest someone else's complex macro as an alternative in the same breath.

As for REAL4/REAL8 vs REAL10, I do agree that size may be an issue if you have large arrays of FP numbers. But again, this is in the same breath as suggesting a complex macro instead of the bloated (sorry about this again) few lines of code.

But for speed, indications are that there is no difference between loading REAL4 or REAL8 to the FPU. Would anybody else on this forum have any factual data on that issue?

Raymond
Posted on 2002-12-24 21:00:06 by Raymond
Raymond, don't appologise, I still dislike my choice of words when I described your method so and ill feelings were most likely caused by myself :( . But forget that for moment.

I take your point about macros. And I've seen too many macros which create terribly bloated code and so I understand your feelings. But this macro is different, it doesn't create any code. Those two examples I gave weren't just functionally identical (i.e at the end of the day doing the same thing) but they they do the same thing the same way. Take this example:
.data

OnePt5 dq 1.5
TwoPt5 dd 2.5

.code
fld1
fld fpc(3.5)
fld fpc(REAL8 4.5)
fld TwoPt5
fld OnePt5

Then look at the dissasembly and you see how clean the macro is
00401062 D9E8                   fld1

00401064 D90530204000 fld dword ptr [402030h]
0040106A DD0534204000 fld qword ptr [402034h]
00401070 D90552304000 fld dword ptr [403052h]
00401076 DD0556304000 fld qword ptr [403056h]

My dislike of your method stemmed from the fact that you used two aspects of the FPU which in general one would try to avoid, loading integer instructions and division as both are very slow relative to loading reals and the other arithmatic intructions. But outside of speed critical algos I doubt it would really make any difference.
Posted on 2002-12-25 05:48:22 by Eóin
IrOn,
MASM does not float. It sinks and stinks. It can only drop floaters in your data section. That means it cannot process instructions like PUSH 5.0. You must instead use the more expensive data memory referencing instruction PUSH , where F5P0 is defined something like F5P0 DD 5.0 . What? You wanna do something like F8P0 DD 4.3+3.7? Forget it. MASM is impotent with respect to floating arithmetic. Only way around that limitation is to manually compute and enter numbers hexually (PUSH 40A00000H). Other more well endowed assemblers don't have that hang up. Until his Billness decides to upgrade, you are a floating cripple while you remain in the MASM zone. Ratch
Posted on 2002-12-25 10:40:51 by Ratch