Was trying a couple of days ago to create an array of structs using FASM
to no avail. Seems that I just dont know the correct syntax (if you can).

MASM example 22 TBBUTTONs array :
ToolInfo TBBUTTON 22 dup(<>)

The best I could come up with combinations of:
ToolInfo TBBUTTON times 22
ToolInfo times 22 TBBUTTON
. . .

All of them failed via compiler error. I did a search but of course there are
not yet many topics, and none of the tutorials I looked at came with such
an example. I know how to access them from other posts I have made,
just need to know how to initially create them.

Thanks!
Posted on 2002-07-29 17:54:34 by Graebel
There's probably a better way of doing this but here goes.
struc POINT {

.x dd ?
.y dd ?
}
virtual at 0
POINT POINT
szPNT = $
end virtual

That declares the structre, now declare the array
; Array of POINTs

Points rb szPNT*22

Access array as follows
; Access element x of 3rd POINT struc in the array

mov [Points+(3*szPNT)+POINT.x],1234

Whats nice about this method is that easily applies to runtime arrays.
invoke GlobalAlloc,GPTR,szPNT*10	; Create array of 10 POINT strucs

mov [eax+(5*szPNT)+POINT.y],1234 ; Access element y of 5th struc
Posted on 2002-07-29 19:12:50 by Eóin
Well, even if there is a more "proper" way to declare them, at least
I can keep porting over my code in the mean time.

This declaration looks kinda funny, but it seems to compile ok. Then
again I dont own a disassembler (never seen one actually), so I cant
verify that the code is ok... but I am liking this version:



struc POINT
{
.x dd ?
.y dd ?
.size = $ - .x
}
POINT POINT


allows accessing the size of the struc via
POINT.size
:alright:

I am not all that "hip" about what POINT POINT is actually *doing*, but
I am guessing it is like in the macros where the name is over riding the
default behaviour? I know its creating a POINT called POINT, but after
this if I try and create another is where I am trying to figure out if its ok...
I am guessing it will bind to the struc POINT and not the name... if so
it simplifies the syntax a good deal.
Posted on 2002-07-29 22:22:20 by Graebel
In Fasm structres are like lables and local labels together. And labels are just numbers. Virtual is a way of controling the numbers a lable is given and makes struc easier.

My example
struc POINT {

.x dd ?
.y dd ?
}
virtual at 0
POINT POINT
szPNT = $
end virtual

Creates three labels POINT.x which equals 0 (As it stared at 0 due to the virtual), POINT.y = 4 and szPNT = 8.

Had I used PNT POINT then the label created would have been PNT.x and PNT.y which would mean in accessing memory I'd need to use those: mov ,1234

This is an example of the power of Fasm, it doesn't require you to come up with two names for each stuc.

And a word on using your struc
struc POINT

{
.x dd ?
.y dd ?
.size = $ - .x
}
POINT POINT

Including the size inside the struc means it actually uses memory in the final app, whereas a label wouldn't. Once off this would be no big deal but lets say in an array of a 100 such strucs, you'll have stored 100 copies of the size of each element, 400 bytes unnecessarly wasted.
Posted on 2002-07-30 12:45:42 by Eóin
E?in, having '.size = $ - .x' in the struc does not take memory - the struc is not increased in size.
Posted on 2002-07-30 12:50:59 by bitRAKE
Damn you bitRAKE your too quick :grin: I just coped on that :rolleyes:
Posted on 2002-07-30 12:58:13 by Eóin
Hey E?in, get a load of this. I was playing around with the struc's
last night and came up with this alternative. I am trying to wrap
some macros around it (with little success btw), but for me this
is much more intuitive.


virtual
struc sizeof
{
[COLOR=blue]; declare sizeof.POINT[/COLOR]
tPOINT POINT
.POINT = $ - tPOINT
[COLOR=blue]; declare sizeof.RECT[/COLOR]
tRECT RECT
.RECT = $ - tRECT
}
sizeof sizeof
end virtual

The code above compiles without complaint and gives a nice intuitive
way to grab sizes. However (I dont know why yet) the code below
does not compile at all. Gives an error about redefinition on line in red.


macro szlbl name
{
t#name name
.name = $ - t#name
}

virtual
struc sizeof
{
szlbl POINT
szlbl RECT
}
[COLOR=red]sizeof sizeof[/COLOR]
end virtual

I *thought* the macros would expand before the interpreter would
see what was going on but that is obviously not the case or else I
would think that the second code snip would be identicle to the first...
Posted on 2002-07-30 15:02:05 by Graebel
This one should work:


macro szlbl name
{
local .lbl
.lbl name
.#name = $ - .lbl
}

virtual at 0
struc sizeof
{
szlbl POINT
szlbl RECT
}
sizeof sizeof
end virtual

"t#name name" wouldn't work because macroinstructions are processed before concatenations, so this structure macro couldn't be correctly recognized.
btw: your approach is very nice!
Posted on 2002-07-30 15:16:20 by Tomasz Grysztar
And it still could be simplified:


macro szlbl name
{
local lbl
lbl name
sizeof.#name = $ - lbl
}

virtual at 0
szlbl POINT
szlbl RECT
end virtual
Posted on 2002-07-30 15:31:40 by Tomasz Grysztar
Thats about what I was getting to but I wasnt finished yet :grin:

I cant quite do what I would *like* to do, but thats as close as I
can get right now. I am still going to look at some alternatives...
anyways, thanks for the help Privalov =)
Posted on 2002-07-30 16:24:42 by Graebel
This one should work: <SNIP>
And it still could be simplified: <SNIP>

Its funny, I tried each of those on both FASM 1.39 and the newer
FASM 1.40 ver3 and none of them seem to want to compile. It
always gives an error about already defined data... I must be off
my rocker and doing something wrong.
Posted on 2002-07-30 20:37:45 by Graebel
If you still have this problem, please show the whole source you are getting this error with.
Posted on 2002-07-31 01:21:11 by Tomasz Grysztar
Ahha!

Well I think I just figured it out. After much fussing with the code, I thought
I would try and move it and then it compiled. I *was* declaring the macro
in Macros.inc and the other snip in User.inc. I am now guessing that macro
(or other) expansion is not applied to included files :alright:

For me, it made since to declare it there. Guess that shows me lol.

Oh well, problem solved =)
It will clutter up my main program now, but I can live with that...
If it should still compile in the included files, then here is the source.
Posted on 2002-07-31 16:19:40 by Graebel
E?in, nice way to access arrays, but when I implemented it, there's this thing:
; Access element x of 3rd POINT struc in the array
mov ,1234


Actually, to access the element x of 3rd POINT struc, I had to:
mov [Points+(2*szPNT)+POINT.x],1234


This has no importance if you imagine that the first POINT struc = 0.
As I'm a newbie, please correct me if I'm wrong.

Maybe we can overcome it with something like this:


macro Putpoint struct, element, value
{
mov [Point+(struct*szPNT)-szPNT+POINT.#element],value
}

Then, to access the element x of 3rd struc, and store 1234:


Putpoint 3,x,1234

I haven't tryed it yet, so tell me if you like it.
Nice day,
sloppy
Posted on 2002-08-19 11:45:20 by slop
Thanks for pointing that out sloppy, you're absolutly right :) .

And your macro idea is nice, perhaps make it a bit more general by allowing the array and structre type be passed as well? This would probably require some standard in defining structre sizes structres, but it could be interesting.

In practice however I find I only then to access arrays in loops useing loop counters so I've never really used my own method myself ;)
Posted on 2002-08-19 13:13:52 by Eóin
Hi E?in,
I've bee thinking of your idea about an standard, but do you think it'd be useful?

I specially like the way to handle run-time arrays of your method:
invoke GlobalAlloc,GPTR,szPNT*10	; Create array of 10 POINT strucs

mov [eax+(5*szPNT)+POINT.y],1234 ; Access element y of 5th struc


to do that with the macro it'd be something like:


Points rb szPNT*22

mov eax, Points ;handler in eax passed to macro
Putstuff 3,x,1234 ;Putstuff always uses eax (pretty standard, I think ;) )

;and for runtime
GlobalAlloc,NULL,szPNT*10
Putstuff 5,y,1234 ;access element y of 5th struc (just created)

And this is the new macro:


macro Putstuff struct,element,value ;uses EAX as handler
{
mov [eax+(struct*szPNT)-szPNT+POINT.#element],value
}

And this is your POINT we're using:


struc POINT {
.x dd ?
.y dd ?
}
virtual at 0
POINT POINT
szPNT = $
end virtual


I enjoy your POINT a lot :), if you can see my point ;)

Now, I'm also interested about your method:
In practice however I find I only then to access arrays in loops useing loop counters so I've never really used my own method myself

Can you explain it, a little?
Posted on 2002-08-21 11:37:25 by slop
Another one approach:


macro array name,struc,count
{
local array,size
virtual at 0
name struc
size = $
end virtual
array: rb size*count
name equ array+size*
}

array pts,POINT,10

Then to put 0 in the x field of fifth point of the structure:


mov [pts 4 + pts.x],0
Posted on 2002-08-21 12:49:57 by Tomasz Grysztar
Privalov, why 'array+size', shouldn't it be just 'array' or 'array-size'?
Then 'mov ,0', right?

I like it better than my approach, but of course, you're in advantage: you're the 'father of the creature', while I'm just a good friend of hers ;)
Posted on 2002-08-22 12:55:54 by slop