News:

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

Structures issue

Started by donkey, December 13, 2010, 04:53:33 PM

Previous topic - Next topic

donkey

Hi Jeremy,

I seem to remember that we have covered this before but I can't remember the solution. I have the following error:

YRT STRUCT
t1 dd ?
t2 db 256 DUP
t3 db 64 DUP
ends

XRT STRUCT
r1 DD
r2 YRT 64 DUP <?>
ends

DATA SECTION
mmm XRT <?>


QuoteLine 21 of assembler source file (DialogTest.Asm):-
Label of this name already declared:-
mmm.r2.t1 dd  0

OBJ file not made

Using GoAsm.Exe Version 0.56.8

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

not sure about GoAsm, Edgar
but, in MASM, you have to refer to the name in ENDS
also - check your define for "r1"   :P
anyways - here is what it would look like for MASM...
YRT STRUCT
        t1 dd ?
        t2 db 256 DUP(?)
        t3 db 64 DUP(?)
YRT ENDS

XRT STRUCT
        r1 dd ?
        r2 YRT 64 DUP <>
XRT ENDS

i am not positive about the "r2" line   :P

donkey

Hi Dave,

In GoAsm the ENDS directive doesn't need the structure name. r2 should be fine. The problem is in DUP, when using structures it does not properly isolate the names of the member of the duplicated structure. This was handled years ago but I just can't remember the syntax or it was broken in some update.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

donkey

Hi Jeremy,

This is how I see the problem. Structures are dynamic at compile time, they change while you add and remove members during development and also depending on compile time options (ie WIN64). Even though it is possible just to replace the entry of a DUP'ed structure with DB BTYECOUNT DUP ?, that is not an optimal solution because every time you change a structure you would have to go through your code to find all references manually. This is because within a structure the following gives an error:

YRT STRUCT
t1 dd ?
t2 db 256 DUP
t3 db 64 DUP
ends

XRT STRUCT
r1 DD
r2 DB (SIZEOF YRT*64) DUP ?
ends

DATA SECTION
mmm XRT <?>


QuoteLine 20 of assembler source file (DialogTest.Asm):-
Material in brackets defined by other material in brackets - please simplify
  In the struct at Line 14 of assembler source file (DialogTest.Asm)

OBJ file not made

So you cannot just use the size of the structure directly. Not a horrible situation in a small program but when considering the headers there are many structures whose size changes due to multiple switches (WIN64, WINVER etc...) and hunting them down and changing them for every build type is quite a bit of work.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jorgon

Hi Edgar
I've replicated this bug on my machine and I should be able to look at this and find a fix in the next day or two.
Jeremy
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

jorgon

Hi Edgar

The error you are getting of Line 21 of assembler source file (DialogTest.Asm):-
Label of this name already declared:-
mmm.r2.t1 dd  0

arises when you assemble the source code in your original post because when combining structures in this way (that is to say using a structure within another structure) GoAsm creates a symbol name which is a concatenation of the labels used within the structure.  So, on the first use of the structure YRT, GoAsm creates the symbol mmm.r2.t1.  That particular part of the structure can be addressed using that symbol.  On the second use of the structure YRT (arising from the fact that it is duplicated) exactly the same symbol is created by GoAsm.  So inevitably, GoAsm baulks at the duplicated symbol name.  If GoAsm allowed the assembly to continue you would end up with 64 symbols all called "mmm.r2.t1"

You can avoid this result by not using any label for YRT as follows:-

YRT STRUCT
t1 dd ?
t2 db 256 DUP
t3 db 64 DUP
ends

XRT STRUCT
r1 DD
   YRT 64 DUP <?>
ends

DATA SECTION
mmm XRT <?>


Alternatively if you needed to address the individual parts of the combined structure, instead of using
r2 YRT 64 DUP <?>
you could label each separately, eg
r2 YRT <?>
r3 YRT <?>
r4 YRT <?>

and so on ..
or in fact simply
r2 YRT
r3 YRT
r4 YRT


So how you would wish to deal with this issue depends on whether and how you need to address each individual part of the combined structure.
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

donkey

Hi Jeremy,

Darn, I was hoping that maybe I missed something and would not have to comb through the headers looking for DUP'ed structures, I don't think there are many. I imagine that I will have to look for any ones that might vary by switches and incorporate those switches since the unlabeled option is not really viable. I am thinking of something like this.

YRT STRUCT
    t1 dd ?
    t2 db 256 DUP
    t3 db 64 DUP
#IF WINVER > NTDDI_WINXP
    t4 db 16 DUP
#ENDIF
ends

#IF WINVER > NTDDI_WINXP
XRT STRUCT
    r1 DD
    r2 DB 340 DUP ?
ends
#ELSE
XRT STRUCT
    r1 DD
    r2 DB 324 DUP ?
ends
#ENDIF


This will work and should not require much editing but does mean keeping a closer eye on any changes to structures in future versions of Windows. Still, it would be nice to have the ability to use SIZEOF in a structure definition, maybe something for your already endless todo list. There is never a need to individually address the repeating structures so the second example is not necessary, I can't think of a situation where anything but repeating DB's would be required. At any rate I will look through the headers and make any changes that are necessary.

PS: Nice to have you back :) How are things in Oz ?

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jorgon

Hi Edgar

Would this be easier to use? :-
YRT STRUCT
    t1 dd ?
    t2 db 256 DUP
    t3 db 64 DUP
#IF WINVER > NTDDI_WINXP
    t4 db 16 DUP
#ENDIF
ends

XRT STRUCT
    r1 DD
#IF WINVER > NTDDI_WINXP
    r2 DB 340 DUP ?
#ELSE
    r2 DB 324 DUP ?
#ENDIF
ends


How are things in Oz?
Wonderful! Thank you Australia for taking me in.


Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

donkey

Hi Jeremy,

Glad to hear that Oz is working for you.

The example you gave is pretty much what I decided to go with, I am looking through the headers trying to spot any potential problems and correct them. I have looked through a few of the headers that change most frequently (commctrl.h and winuser.h) and I can't see this being a big issue since usually when a structure is used within another it is not repeated. In the rare case where it is I can make a note to check it in the sub-structure definition.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable