Author Topic: Dumb question: how to declare a nested structure?  (Read 7351 times)

NoCforMe

  • Member
  • **
  • Posts: 89
Dumb question: how to declare a nested structure?
« on: April 22, 2015, 05:32:52 PM »
Just a question about MASM syntax: suppose a guy wanted to do something like this:

Code: [Select]
$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:

Code: [Select]
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 (<>).

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: Dumb question: how to declare a nested structure?
« Reply #1 on: April 22, 2015, 10:59:12 PM »
try this one...

Code: [Select]
MoveHandles $moveHandleStruct $maxActiveItems DUP(<>)symbol type definition

NoCforMe

  • Member
  • **
  • Posts: 89
Re: Dumb question: how to declare a nested structure?
« Reply #2 on: April 23, 2015, 11:57:34 AM »
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).

rrr314159

  • Member
  • *****
  • Posts: 1382
Re: Dumb question: how to declare a nested structure?
« Reply #3 on: April 23, 2015, 01:08:12 PM »
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

  • Member
  • **
  • Posts: 89
Re: Dumb question: how to declare a nested structure?
« Reply #4 on: April 23, 2015, 01:10:10 PM »
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:
Code: [Select]
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?

rrr314159

  • Member
  • *****
  • Posts: 1382
Re: Dumb question: how to declare a nested structure?
« Reply #5 on: April 23, 2015, 01:52:31 PM »
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

  • Member
  • **
  • Posts: 89
Re: Dumb question: how to declare a nested structure?
« Reply #6 on: April 23, 2015, 02:55:30 PM »
Well, I came up with this:

Code: [Select]
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:

Code: [Select]
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. ...

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: Dumb question: how to declare a nested structure?
« Reply #7 on: April 23, 2015, 05:00:06 PM »
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
Code: [Select]
$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

  • Member
  • *****
  • Posts: 1735
    • https://github.com/nidud/asmc
Re: Dumb question: how to declare a nested structure?
« Reply #8 on: April 23, 2015, 09:01:21 PM »
Code: [Select]
MoveHandles LABEL $moveHandleStruct
db  SIZE $moveHandleStruct * $maxActiveItems DUP (?)

rrr314159

  • Member
  • *****
  • Posts: 1382
Re: Dumb question: how to declare a nested structure?
« Reply #9 on: April 23, 2015, 10:49:53 PM »
@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

  • Member
  • *****
  • Posts: 1735
    • https://github.com/nidud/asmc
Re: Dumb question: how to declare a nested structure?
« Reply #10 on: April 24, 2015, 12:06:40 AM »
struct.asm:
Code: [Select]
.xlist
include \masm32\include\masm32rt.inc
.list

$maxActiveItems EQU 16

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

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

.data?

MoveHandle LABEL $mhStruct
db  SIZE $mhStruct * $maxActiveItems * 8 DUP (?)

MoveHandles LABEL $moveHandleStruct
db  SIZE $moveHandleStruct * $maxActiveItems DUP (?)

.code

start:
printf("SIZE MoveHandle:\t%d\n",SIZE MoveHandle)
mov eax,MoveHandle._X
add eax,MoveHandle[SIZE $mhStruct * 1]._X
add eax,MoveHandle[SIZE $mhStruct * 2]._X

printf("SIZE MoveHandles:\t%d\n",SIZE MoveHandles)
mov eax,MoveHandles._mh._X
add eax,MoveHandles._mh[SIZE $mhStruct * 1]._X
add eax,MoveHandles._mh[SIZE $mhStruct * 2]._X

inkey chr$("--- ok ---", 13)
exit
end start

build:
Code: [Select]
\masm32\bin\ml -c -coff struct.asm
\masm32\bin\link.exe /map /subsystem:console /libpath:\masm32\lib struct.obj

result:
Code: [Select]
SIZE MoveHandle:        16
SIZE MoveHandles:       128
--- ok ---

nidud

  • Member
  • *****
  • Posts: 1735
    • https://github.com/nidud/asmc
Re: Dumb question: how to declare a nested structure?
« Reply #11 on: April 24, 2015, 12:54:23 AM »
this seems to work
Code: [Select]
$moveHandles STRUCT
  h $moveHandleStruct $maxActiveItems DUP (<>)
$moveHandles ENDS

.data?
Handles $moveHandles <>
...
printf("SIZE Handles:\t%d\n",SIZE Handles)

Code: [Select]
SIZE Handles:   2048
--- ok ---


dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: Dumb question: how to declare a nested structure?
« Reply #13 on: April 24, 2015, 01:45:30 AM »

nidud

  • Member
  • *****
  • Posts: 1735
    • https://github.com/nidud/asmc
Re: Dumb question: how to declare a nested structure?
« Reply #14 on: April 24, 2015, 01:57:10 AM »
there is something fishy here

qword is in this post dated November 16, 2011, 09:34:56 PM giving a link to the future...