I'm getting an error when assembling the following code:
TPRECISION typedef QWORD
TPRECT STRUCT 16
g TPRECISION -2.0
d TPRECISION 1.0
h TPRECISION 1.2
b TPRECISION -1.2
TPRECT ENDS
; And then:
.data
frect TPRECT <>
Masm gives an error for the last line: "error A2050: real or BCD number not allowed"
However, if i use plainly "QWORD" or "dq" as the type instead of "TPRECISION", it works...
Is there something i am doing wrong or is it a limitation of masm?
Is there a way around it or a way to force masm to encode a number in real-double precision?
The only way around that i see is encoding the number by hand, and giving masm the encoded hex number. :(
Thanks!
vg,
QWORD is an integer data type so you cannot point floating point data at it. For 64 bit use REAL8.
Thanks Hutch,
Sorry, I wasn't aware that there was a specific type for real numbers :red
But i just tried using REAL8, but it doesn't work either
I changed:
TPRECISION typedef QWORD
to:
TPRECISION typedef REAL8
but it's giving me the same error..
vg
The next trick is you cannot load an immediate into a floating point register. It has to be a memory operand or a floating point register.
Here are the macros from masm32 to load floating point registers.
; --------------------------------------------
; FLD does not accept immediate operands. These
; macros emulate loading an immediate value by
; loading the value into the .DATA section.
; EXAMPLE : fld8 1234.56789
; --------------------------------------------
fld4 MACRO fpvalue
LOCAL name
.data
name REAL4 fpvalue
align 4
.code
fld name
ENDM
fld8 MACRO fpvalue
LOCAL name
.data
name REAL8 fpvalue
align 4
.code
fld name
ENDM
fld10 MACRO fpvalue
LOCAL name
.data
name REAL10 fpvalue
align 4
.code
fld name
ENDM
Quote from: hutch-- on January 31, 2006, 04:51:30 AM
QWORD is an integer data type so you cannot point floating point data at it. For 64 bit use REAL8.
Yes you can. MASM converts it into its representation in the size provided (DWORD, QWORD or TBYTE).
I've never come across the typedef issue before (since I very rarely typedef anything besides prototypes) but the issue may be with initialising the structure in it's definition. Try this:
TPRECT STRUCT
g TPRECISION ?
d TPRECISION ?
h TPRECISION ?
b TPRECISION ?
TPRECT ENDS
.data
frect TPRECT <-2.0, 1.0, 1.2, -1.2>
Also, is there any particular reason for aligning each member on a 16-byte boundary (the 16 in TPRECT STRUCT 16)? This will put 8 bytes worth of padding in between each element (since they are 8 bytes) and effectively double the size of the structure.
Thanks again for your help, but there's still something that doesn't work out...
I don't see where i could be wrong, so i made a test program from scratch:
.686
.model flat, stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
TPRECISION typedef REAL8
TPRECT STRUCT 16
g TPRECISION -2.0
d TPRECISION 1.0
h TPRECISION 1.2
b TPRECISION -1.2
TPRECT ENDS
.data
frect TPRECT <>
.code
start:
xor eax,eax
invoke ExitProcess,eax
end start
This program won't assemble (i'm using ml 6.15).
Here's the error message:
"masmtst.asm(24) : error A2050: real or BCD number not allowed"
I saw Zooba's answer as i was replying, i will try initialising the structure like you typed.
I thought "16" was going to align the whole structure on a 16 bytes boundary, not every item! lol i'm going to change that as well.
Thanks, back in a minute..
Thanks!!! it's working that way :bg :U
TPRECISION typedef REAL8
TPRECT STRUCT 16
g TPRECISION ?
d TPRECISION ?
h TPRECISION ?
b TPRECISION ?
TPRECT ENDS
.data
frect TPRECT <-2.0, 1.0, 1.2, -1.2>
I'm using a typedef so i don't have to have 2 versions of the same function around. That way, when i feel like seeing the speed/quality difference between float and double, i just have one word to change :)
vg
The structure is syntactically wrong. They normally do not support loading a value.
TPRECT STRUCT 16
g TPRECISION -2.0
d TPRECISION 1.0
h TPRECISION 1.2
b TPRECISION -1.2
TPRECT ENDS
Try it like this.
TPRECT STRUCT
g REAL8 ?
d REAL8 ?
h REAL8 ?
b REAL8 ?
TPRECT ENDS
Zooba has shown you how to write the structure and then fill the structure from the .DATA section.
Quote from: vg on January 31, 2006, 05:55:21 AM
I thought "16" was going to align the whole structure on a 16 bytes boundary, not every item! lol i'm going to change that as well.
Hehe, that's exactly what I first thought until it was explained to me :wink :U
To align the whole structure, put ALIGN 16 before each definition:
.data
ALIGN 16
frect TPRECT <-2.0, 1.0, 1.2, -1.2>
ALIGN 16 ; not strictly necessary since the structure will align on a 16-byte boundary anyway
frect2 TPRECT <1.0, 2.0, 3.0, 4.0>
Hutch,
I've found that structures will support a 'default' value for an item as defined in the STRUCT block. For example (from my current project):
Instruction STRUCT
AddrSupported DWORD 0
InhEncoding BYTE 8 DUP (0) ; first byte of each encoding indicates the length
ImmEncoding BYTE 8 DUP (0) ; ImmEncoding also used for relative addr. mode
DirEncoding BYTE 8 DUP (0)
ExtEncoding BYTE 8 DUP (0)
IndexedEncoding BYTE 8 DUP (0)
lpHandler DWORD 0 ; handler if AddrSupported contains ADDR_SPECIAL
Instruction ENDS
Then the definitions only require different values to be filled and empty items are filled from the definition.
_ABA Instruction <ADDR_INH, <2, 018h, 006h>>
_ASR Instruction <ADDR_EXT or ADDR_INDEXED, <>, <>, <>, <1, 077h>, <1, 067h>>
_DCB Instruction <ADDR_SPECIAL, <>, <>, <>, <>, <>, CONSTANT_handler>
Presumably in an uninitialised data section the values have no effect, and apparently TYPEDEFs are not supported (yet? probably never... :( ).
Quote from: zooba on January 31, 2006, 06:10:41 AM
Presumably in an uninitialised data section the values have no effect, and apparently TYPEDEFs are not supported (yet? probably never... :( ).
Actually it works, but only with integers, not real numbers.
I must have seen this kind of declaration on a web page when i was looking for examples on structures with masm, but i can't remember where...
Or you can do it the hard way :bg
DD 03f4ccccdr ; 0.8