News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Dumb question: how to declare a nested structure?

Started by NoCforMe, April 22, 2015, 05:32:52 PM

Previous topic - Next topic

NoCforMe

Just a question about MASM syntax: suppose a guy wanted to do something like this:


$maxActiveItems EQU 16

$mhStruct STRUCT
  _handle HWND ?
  _flags DD ?
  _X DD ?
  _Y DD ?
$mhStruct ENDS

$moveHandleStruct STRUCT
  _mh $mhStruct 8 DUP (<>)
$moveHandleStruct ENDS


So cool, I've defined a nested structure. MASM likes that OK, is happy. But now when I try to declare a variable (an array of structs) using it:


MoveHandles LABEL $moveHandleStruct
  $moveHandleStruct $maxActiveItems DUP (<>)


MASM complains, says "nested structure improperly initialized". So how do I declare this? I want it uninitialized (it's in .data?). What's the correct syntax here?

(Just to be crystal clear: I want to declare an array, with $maxActiveItems members, of $moveHandleStruct, each of which contains 8 $mhStructs. And the error is on the 2nd line of the declaration, the one that says $moveHandleStruct  $maxActiveItems DUP (<>).
Assembly language programming should be fun. That's why I do it.

dedndave

try this one...

MoveHandles $moveHandleStruct $maxActiveItems DUP(<>)
symbol type definition

NoCforMe

Nope, same error. That's really the same declaration, just with a label in front of it.

Any other ideas? I looked in the copy of the MASM manual (PDF) I have, but no help there. What I need is the specific syntax for initializing a nested structure (even though I'm not really initializing it).
Assembly language programming should be fun. That's why I do it.

rrr314159

Hi nocforme,

the simple answer is, use JWasm.

I once knew what ML wants for this statement ... something very strange-looking. Sooner or later I'll remember, or find it. This is one (of many) reasons I stopped using ML. For now, recommend u use JWasm, which accepts it just the way you've written it.
I am NaN ;)

NoCforMe

Thanks, but I'm not about to switch assemblers at this point just because of a small roadblock. I assume there's a way to do this, so hopeful the magic incantation needed will reveal itself soon.

-------------------------------------------------------------------------------
Well, it hasn't yet, but I found a workaround. Very ugly:

MoveHandles $moveHandleStruct <>, <>, <>, <>, <>, <>, <>, <>,\
  <>, <>, <>, <>, <>, <>, <>, <>


I suppose I could ameliorate this a little by writing a macro to do the "duping". BTW, this seems to be a genetic defect of MASM 6.x, at least according to this from Microsoft: ftp://ftp.microsoft.com/misc1/DEVELOPR/MASM/KB/Q94/9/12.TXT

What would that macro look like?
Assembly language programming should be fun. That's why I do it.

rrr314159

Well, I'll see if I can find the "magic incantation" - it's shorter than what you've got. But, not sure u understand what should be involved in "switching assemblers". JWasm ought to simply work, with any luck it will just compile your code exactly as it is. No changes needed at all, not like switching to GoAsm or something; it should be a direct replacement. I used both side-by-side for months, until I dropped ML. Just download it for free, put it in bin, rename ML to ML_old, rename JWasm to ML, done, that's it. Admittedly there may be a hiccup (probably some little thing I'm forgetting), but it should be about that easy.

As for the macro, use a REPEAT loop. Initialize a blank string above and add the copies of <>, in the loop using textequ. U could look at macros like fn in macros.asm where the author does similar to make a string with all the invoke arguments, using CATSTR instead.

But there are couple little problems, one is, you need to escape < and > since they're reserved symbols. See how that's done in cfm$ macro, or qWord's rcvx. And it would be easiest to create the entire statement of the line not just the duplicated <>'s. Again, see fn in macros.asm. Use a macro function and return the entire string with EXITM<$created_string>. qWord knows this stuff like the back of his hand, ask him

Or try JWasm, take 5 minutes if that, you'll never regret it
I am NaN ;)

NoCforMe

Well, I came up with this:


DUPSTRUCT MACRO structname, rptcount
LOCAL txt
txt TEXTEQU <structname >

REPEAT rptcount
@CATSTR (<!<!>, >, txt)
ENDM
@SUBSTR (txt, 1, @SizeStr(%txt) - 1)
EXITM txt

DUPSTRUCT ENDM


to be invoked thus:


DUPSTRUCT $moveHandleStruct, $maxActiveItems


but it doesn't work (error is "unmatched macro nesting") ...

======================================================

Took off the label ("DUPSTRUCT") from the last ENDM which removed that error, but now I get a syntax error when I invoke the macro.

This stuff makes my head hurt. All those substitution symbols, evaluation symbols, "%", "&", etc. ...
Assembly language programming should be fun. That's why I do it.

dedndave

you're right, it should be simple - lol

but, the work-around seems simple enough
i would guess you're going to be addressing with a register, anyways
$maxActiveItems EQU 16

$mhStruct STRUCT
  _handle HWND ?
  _flags DD ?
  _X DD ?
  _Y DD ?
$mhStruct ENDS

    .DATA?

MoveHandles $mhStruct 8*$maxActiveItems dup(<>)


at the end of the day, it's an array of 4-dword elements   :P

tomorrow, i'll see if i can figure out the syntax issue

nidud

#8
deleted

rrr314159

@nidud, sure probably it's good enough to just reserve the bytes but there are differences. Your way, type (movehandles) will return "1" instead of the correct value (which would be 4 I think?). Also Size won't work. Can't think of anything else at the moment. It's not unreasonable to want to do it right, even if he's not using type or size right now. There are also possible objections to other work-arounds. I looked for it, but can't find the official ML way - I remember it's some ugly syntax.

I have a list of a couple dozen things about ML (actually, ML64; most apply to ML also) like nit-picky syntax issues, which JWasm handles better. The worst is, if unitialized data goes over a mere 10k or so ML takes a long time to compile. A few 100,000 takes minutes, while JWasm takes microseconds. Also JWasm is under active development (counting one Australian transplant) while ML is under active deprecation. Admittedly, ML is better in a couple things - which is why I have both and can switch with one keystoke (either "make j" or "make m" as desired). JWasm is free, better, almost 100% compatible, everybody on this site uses it, ...
I am NaN ;)

nidud

#10
deleted

nidud

#11
deleted



nidud

#14
deleted