News:

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

Typedef on floating point number

Started by vg, January 31, 2006, 04:11:29 AM

Previous topic - Next topic

vg

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!

hutch--

vg,

QWORD is an integer data type so you cannot point floating point data at it. For 64 bit use REAL8.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

vg

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

hutch--

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
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

zooba

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.

vg

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

vg

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

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

zooba

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... :( ).

vg

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

Mincho Georgiev

Or you can do it the hard way  :bg
DD 03f4ccccdr         ; 0.8