The MASM Forum

General => The Campus => Topic started by: NoCforMe on April 22, 2015, 05:32:52 PM

Title: Dumb question: how to declare a nested structure?
Post by: NoCforMe on April 22, 2015, 05:32:52 PM
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 (<>).
Title: Re: Dumb question: how to declare a nested structure?
Post by: dedndave on April 22, 2015, 10:59:12 PM
try this one...

MoveHandles $moveHandleStruct $maxActiveItems DUP(<>)
symbol type definition
Title: Re: Dumb question: how to declare a nested structure?
Post by: NoCforMe 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).
Title: Re: Dumb question: how to declare a nested structure?
Post by: rrr314159 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.
Title: Re: Dumb question: how to declare a nested structure?
Post by: NoCforMe 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:

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?
Title: Re: Dumb question: how to declare a nested structure?
Post by: rrr314159 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
Title: Re: Dumb question: how to declare a nested structure?
Post by: NoCforMe on April 23, 2015, 02:55:30 PM
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. ...
Title: Re: Dumb question: how to declare a nested structure?
Post by: dedndave 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
$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
Title: Re: Dumb question: how to declare a nested structure?
Post by: nidud on April 23, 2015, 09:01:21 PM
deleted
Title: Re: Dumb question: how to declare a nested structure?
Post by: rrr314159 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, ...
Title: Re: Dumb question: how to declare a nested structure?
Post by: nidud on April 24, 2015, 12:06:40 AM
deleted
Title: Re: Dumb question: how to declare a nested structure?
Post by: nidud on April 24, 2015, 12:54:23 AM
deleted
Title: Re: Dumb question: how to declare a nested structure?
Post by: dedndave on April 24, 2015, 01:31:15 AM
 :biggrin:
maybe qWord has the answer....

http://www.masmforum.com/board/index.php?topic=17738.msg149418#msg149418 (http://www.masmforum.com/board/index.php?topic=17738.msg149418#msg149418)
Title: Re: Dumb question: how to declare a nested structure?
Post by: dedndave on April 24, 2015, 01:45:30 AM
Jochen also has a work-around using REPEAT

http://www.masmforum.com/board/index.php?topic=17738.msg149607#msg149607 (http://www.masmforum.com/board/index.php?topic=17738.msg149607#msg149607)
Title: Re: Dumb question: how to declare a nested structure?
Post by: nidud on April 24, 2015, 01:57:10 AM
deleted
Title: Re: Dumb question: how to declare a nested structure?
Post by: dedndave on April 24, 2015, 02:18:51 AM
all the links in the old forum that start with "masm32" must be edited to "masmforum"   :biggrin:

http://masmforum.com/board/index.php?topic=1700.msg17265#msg17265 (http://masmforum.com/board/index.php?topic=1700.msg17265#msg17265)
Title: Re: Dumb question: how to declare a nested structure?
Post by: jj2007 on April 24, 2015, 02:18:59 AM
Yeah, we have aliens here, and they use time machines, too 8)
http://www.masmforum.com/board/index.php?topic=1700.0
Title: Re: Dumb question: how to declare a nested structure?
Post by: nidud on April 24, 2015, 03:48:58 AM
deleted
Title: Re: Dumb question: how to declare a nested structure?
Post by: MichaelW on April 24, 2015, 11:04:13 AM
It does look like another MASM bug. At least for ML 6.14 and 6.15 DUP works as expected when it's embedded in the structure declaration.

;===============================================================================
include \masm32\include\masm32rt.inc
;===============================================================================
S1 STRUCT
    x DWORD ?
    y DWORD ?
S1 ENDS
S2 STRUCT
    s1 S1 2 dup(<>)
S2 ENDS
S3 STRUCT
    s2 S2 16 dup(<>)
S3 ENDS
;===============================================================================
.data
    s3 S3 <>
.code   
;=============================================================================== 
start:
;===============================================================================
    printf("%d\n\n",sizeof S3)
   
    mov   esi, alloc(sizeof S3)   
    mov   [esi].S3.s2.s1.x, 1
    mov   [esi].S3.s2.s1[8].x, 2   
    mov   [esi].S3.s2[32].s1.y, 3

    push  [esi].S3.s2.s1.x
    pop   s3.s2.s1.x
    push  [esi].S3.s2.s1[8].x   
    pop   s3.s2.s1[8].x   
    push  [esi].S3.s2[32].s1.y
    pop   s3.s2[32].s1.y
       
    printf("%d\n",s3.s2.s1.x)
    printf("%d\n",s3.s2.s1[8].x)
    printf("%d\n\n",s3.s2[32].s1.y)

    free  esi
    inkey
    exit
end start
;===============================================================================


00401021 C70601000000           mov     dword ptr [esi],1
00401027 C7460802000000         mov     dword ptr [esi+8],2
0040102E C7462403000000         mov     dword ptr [esi+24h],3
00401035 FF36                   push    dword ptr [esi]
00401037 8F0500304000           pop     [off_00403000]
0040103D FF7608                 push    dword ptr [esi+8]
00401040 8F0508304000           pop     [off_00403008]
00401046 FF7624                 push    dword ptr [esi+24h]
00401049 8F0524304000           pop     [off_00403024]



Title: Re: Dumb question: how to declare a nested structure?
Post by: NoCforMe on April 24, 2015, 12:01:38 PM
Quote from: dedndave 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

[insert code example here]

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

Thanks. I'm going to go this route for now, as it's nice and simple (just have to remember to bunch the array elements in groups of 8 ). Yes, using a register to index them.

If someone figures out how to make MASM do this, cool. Will keep checking back here.
Title: Re: Dumb question: how to declare a nested structure?
Post by: dedndave on April 24, 2015, 12:32:55 PM
Michael's solution in reply #18 looks like it has wheels   :t

i'd call that as near as it gets

$maxActiveItems EQU 16

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

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

$HandleArray STRUCT
  $moveHandleStruct $maxActiveItems DUP(<>)
$HandleArray ENDS

    .DATA?

MoveHandles $HandleArray <>


i say Michael's - i guess it's an implementation of qWord's method that i linked earlier
Title: Re: Dumb question: how to declare a nested structure?
Post by: MichaelW on April 24, 2015, 01:20:35 PM
Quote from: dedndave on April 24, 2015, 12:32:55 PM
i say Michael's - i guess it's an implementation of qWord's method that i linked earlier

I did mine at home where I don't currently have a working Internet connection (due to a hardware failure), and while I did not recall qWord's post, that could well be where the idea came from.