flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Array of structs in a struct

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Big Red



Joined: 25 Feb 2005
Posts: 43
Big Red 01 Dec 2009, 17:10
Hey there FASM people, long time no see. Smile

I need to make a struct where one member is an array of structs. I couldn't find very much using the forum search (there must be other posts about it I'm sure, but it's not quite google). There was one short topic, with the help of which I planned on doing this:

Code:
struct STRUCTURE1
      Member1    dd ?
      Member2    dd ?
ends

struct STRUCTURE2
      Member1    dd ?
      union
         Member2Array STRUCTURE1
         rb 8*(sizeof.STRUCTURE1)
      ends
      Member3    dd ?
ends       

(where 8 is the size of the array)
    


So Member2Array is an array of 8 STRUCTURE1s.

The rb was someone else's idea and this seems to work so far, but is there a better way of doing it now? I'm going to need a ton of these, and 4 lines is a lot to emulate a dup instruction, not to mention there's already unions and this will get confusing. If not, would it work (in all cases) to put the union...ends into a macro and call it in one line?

I've been using FASM 1.66 for a while so I'm kind of behind, but looked at the 1.68 manual and it doesn't talk about it.
Post 01 Dec 2009, 17:10
View user's profile Send private message Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 09 Dec 2009, 00:42
The only way to get it on one line is to:
Code:
Member2Array db sizeof.STRUCTURE1*8 dup(?)    

Then access the 5th element of mystruct (STRUCTURE2) like:
Code:
mystruct STRUCTURE2
mov     eax, [mystruct.Member2Array.Member1 + sizeof.STRUCTURE2*4]    

I don't know if this is easier, just another way.

Oh, by the way, welcome back! your from Canada, if I remember correctly?


Last edited by madmatt on 09 Dec 2009, 23:51; edited 1 time in total
Post 09 Dec 2009, 00:42
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 09 Dec 2009, 04:27
Code:
struct STRUCTURE1
      Member1    dd ?
      Member2    dd ?
ends

struct STRUCTURE2
      Member1    dd ?
      union
         Member2Array STRUCTURE1
         rb 8*(sizeof.STRUCTURE1)
      ends
      Member3    dd ?
ends       
    


How about,
Code:
struct STRUCTURE1
      Member1    dd ?
      Member2    dd ?
ends

struct STRUCTURE2
      Member1    dd ?
      Member2Array: rept 8 { @@ STRUCTURE1 }
      Member3    dd ?
ends       
    


The @@ might cause some problems if you're jumping over the structures, but (since i'm using the linux version i can't test) you might be able to leave them off entirely. You might also be able to pull something off with the local directive, as well.
Post 09 Dec 2009, 04:27
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 09 Dec 2009, 05:05
kohlrak, it fails with "Error: Symbol already defined" at "ends" line. The offending instruction is "label STRUCTURE2.@@". Also it is the problem that "Member2Array" symbol won't participate in the structure because struct macro can't see it.

I think the best way is just the one proposed by madmatt or "Member2Array rb sizeof.STRUCTURE1*8". The code madmatt posted is accessing the 5th element actually. If such direct accesses are needed then defining the structure like this may help:
Code:
struct STRUCTURE1
      Member1    dd ?
      Member2    dd ?
ends

struct STRUCTURE2
      Member1    dd ?
  union
    struct
    rept 8 n:0
    {
      Member2Array_#n#_ STRUCTURE1
    }
    ends
    Member2Array rb sizeof.STRUCTURE1*8

  ends
      Member3    dd ?
ends

alpha STRUCTURE2

; All these instructions access the 7th element
mov eax, [alpha.Member2Array_6_.Member2]
mov edx, [alpha.Member2Array_0_.Member2 + sizeof.STRUCTURE1*6]
mov ecx, dword [alpha.Member2Array + STRUCTURE1.Member2 + sizeof.STRUCTURE1*6]    
Post 09 Dec 2009, 05:05
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 09 Dec 2009, 10:40
a different approach:

Code:
struct S1
  m1  dd ?
  m2  dd ?
ends

struct S2
 m1 dd ?
 virtual at S2.m1   ;<--- note !!!!!!
   ;rept 8 i:0 { ma#i S1 i+"a",i+"0"}  ;<--- comment filling
   rept 8 i:0 { ma#i S1}  ;<--- use this line
  end virtual
 m3  dd ?
ends

    

usage:
Code:
  alfa S2

  ....

  mov [alfa.m1],1
  mov [alfa.m3],3

  mov [alfa.ma0.m1],00000001h
  mov [alfa.ma0.m2],00000002h
  mov [alfa.ma1.m1],00010001h
  mov [alfa.ma1.m2],00010002h
  mov [alfa.ma7.m1],00070001h
  mov [alfa.ma7.m2],00070002h
    


Enjoy,
hopcode Smile
Post 09 Dec 2009, 10:40
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 09 Dec 2009, 13:57
hopcode, what's is the purpose of that virtual block? Removing it doesn't seems to do any harm (all your instructions still reference to the same addresses), and there is the problem that alfa.ma doesn't exists (that's why I've used an union plus an anonymous struct). I guess you actually wanted to define a field "ma" first and then follow it with "virtual S2.ma", but as you can see it has no effect unfortunately (although a trick like that would work inside a preprocessor's struc).
Post 09 Dec 2009, 13:57
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 09 Dec 2009, 20:46
LocoDelAssembly wrote:
hopcode, what's is the purpose of that virtual block?

any useful purpouse.Smile
sometime i leave instructions thru the code only to test preprocessor
behaviour.
I think the simplest solution is the one from madmatt.
Anyway, this
Code:
struct S1
  m1  dd ?
  m2  dd ?
ends

struct S2
 m1 dd ?
 rept 8 i:0 {ma#i S1}
 m3 dd ?
ends

; All these instructions access the 7th element
  mov eax,[alfa.ma7.m2]
  mov edx,[alfa.ma0.m2 + sizeof.S1*7]
  mov ecx,[alfa.ma0 + S1.m2 + sizeof.S1*7]

  ;--- ok and ...

  mov ebx,[alfa.ma0]    ;implicit value, dword m1
  mov ebx,alfa.ma0 ;offset of alfa.m2
  mov ebx,alfa.ma0 + S1.m2 + sizeof.S1*7 ;offset of 7th element
  mov ebx,alfa.ma7     ;offset of 7th element

  mov [alfa.m1],1
  mov [alfa.ma0.m1],2
  mov [alfa.m3],3

 ;etc...testing
  mov [alfa.ma1.m1],011111111h
  mov [alfa.ma1.m2],011112222h
  mov [alfa.ma3.m1],033331111h
  mov [alfa.ma3.m2],033332222h
  mov [alfa.ma7.m1],077771111h
  mov [alfa.ma7.m2],077772222h
    


or , if the name m2 is strictly required,
where ma0 corresponds to m2 and
array is from m1->m7, the same result from the code
here above

Code:
struct S2
 m1 dd ?
 m2 S1 
 rept 7 i:1 { ma#i S1}
 m3 dd ?
ends
    
Post 09 Dec 2009, 20:46
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 09 Dec 2009, 21:34
I think it should be either, my code or your first code in your post above this one. Having to access the first element of the array in a special way than the rest doesn't sounds too handy, for instance in situations like this:
Code:
; Init code of stack variables
  xor eax, eax
  mov [alpha.m2.m1], eax
  mov [alpha.m2.m2], eax

; Now the rest of the elements
rept X_MINUS_ONE i:1
{
  mov [alpha.ma#i#.m1], eax
  mov [alpha.ma#i#.m2], eax
}    
Post 09 Dec 2009, 21:34
View user's profile Send private message Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 09 Dec 2009, 23:50
LocoDelAssembly wrote:
The code madmatt posted is accessing the 5th element actually.


Yeh, silly error on my part, thanks for pointing that out.
Post 09 Dec 2009, 23:50
View user's profile Send private message Reply with quote
Big Red



Joined: 25 Feb 2005
Posts: 43
Big Red 08 Feb 2010, 23:46
Thanks for the replies folks. Sorry I'm so horribly late again.

Actually the indexed names look very nice. I was hoping for a one-liner in the struct definitions, which seems Matt had the only working solution for, but the access code is a bit excessive. It's probably better to simplify the code than the struct definitions, so might go for one of those two solutions instead.

madmatt: Yep, still in Canada, thanks Smile
Post 08 Feb 2010, 23:46
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji 09 Feb 2010, 00:14

I dream of the day I can write :
Code:
struct my_structA
 A0 dd ?
 A1 dd ?
 A2 db ?
ends

array_1 my_structA 25 dup <0x0004E708, 0x00000001, 0x55>
    
We talk about this for a long time ...
This seems to be a need for everyone ... no ?
I think it should not be very complicated to implement this feature in FASM.
This would be a great improvement for FASM.


_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 09 Feb 2010, 00:14
View user's profile Send private message Send e-mail Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Feb 2010, 02:03
ouadji,

How about extending times directive?
Code:
struc times [arg] {
common
  match n def, arg \{
    . def
    rept n-1 i:1 \\{ .\\#_\\#i def \\}
  \}
}
array_1 times 25 my_structA 0x0004E708, 0x00000001, 0x55    
It works inside struct/ends too (though I haven't tested it thoroughly).
Post 09 Feb 2010, 02:03
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji 09 Feb 2010, 03:50

baldr,


Shocked

yes, it works !!

But ... where is the declaration of this extended directive in the FASM package ?
FASM documentation explains the directive "times" ,
but nothing about this extended directive (???)

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 09 Feb 2010, 03:50
View user's profile Send private message Send e-mail Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Feb 2010, 03:58
ouadji,

That macro was just invented. Wink
By the way, slight modification makes it more interesting:
Code:
struc times [arg] {
common
  match n def, arg \{
    rept 1 %:1 \\{ . def  \\}
    rept n-1 %:2 \\{ .\\#_\\#% def \\}
  \}
}    
Now it even replaces % inside data definitions with 1…n. Probably 0…n-1 should be used, but original times control directive defines % as 1-based.
Post 09 Feb 2010, 03:58
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 09 Feb 2010, 05:21
ouadji wrote:
But ... where is the declaration of this extended directive in the FASM package ?
FASM documentation explains the directive "times" ,
but nothing about this extended directive (???)
You are asking a lot to expect a freshly minted new macro invented by baldr in just these last few hours to be retroactively documented in the fasm package Arrow ---> Confused
Post 09 Feb 2010, 05:21
View user's profile Send private message Visit poster's website Reply with quote
alorent



Joined: 05 Dec 2005
Posts: 221
alorent 09 Feb 2010, 08:25
baldr wrote:
ouadji,

How about extending times directive?
Code:
struc times [arg] {
common
  match n def, arg \{
    . def
    rept n-1 i:1 \\{ .\\#_\\#i def \\}
  \}
}
array_1 times 25 my_structA 0x0004E708, 0x00000001, 0x55    
It works inside struct/ends too (though I haven't tested it thoroughly).


Great work!!!

I thought that FASM already had some ways to define elements in a structure (though I never needed it). Isn't it possible to do structure initialization in FASM?

Anyway, it would be nice to have that feature as proposed by ouadhi in the MASM.inc package maybe?. It would be nice to reuse the MASM syntax for that:

Code:
array_1 my_structA 25 dup <0x0004E708, 0x00000001, 0x55>    


I'm loving this FASM flexibility Smile
Post 09 Feb 2010, 08:25
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji 09 Feb 2010, 10:08

baldr invents macros even in sleep. Razz

Hats off ! a master of macro language.

great work ! Shocked


_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 09 Feb 2010, 10:08
View user's profile Send private message Send e-mail Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji 09 Feb 2010, 16:28

baldr,

i don't understand the difference between :

a)
Code:
struc times [arg] { 
common 
  match n def, arg \{ 
    . def 
    rept n-1 i:1 \\{ .\\#_\\#i def \\} 
  \} 
}
    
and
b)
Code:
struc times [arg] { 
common 
  match n def, arg \{ 
    rept 1 %:1 \\{ . def  \\} 
    rept n-1 %:2 \\{ .\\#_\\#% def \\} 
  \} 
}
    

The first and the second, work fine !
I don't see difference (in memory, with a debugger)

Arrow What can i do with the second macro, that the first doesn't allow ?

thank you for your help.

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 09 Feb 2010, 16:28
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 09 Feb 2010, 18:11
ouadji wrote:
i don't understand the difference between :
What can i do with the second macro, that the first doesn't allow ?
baldr, just a few posts ago, wrote:
Now it even replaces % inside data definitions with 1…n. Probably 0…n-1 should be used, but original times control directive defines % as 1-based.
Post 09 Feb 2010, 18:11
View user's profile Send private message Visit poster's website Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji 09 Feb 2010, 19:11
Thank you for your reply revolution.
Quote:

baldr, just a few posts ago, wrote:

Now it even replaces % inside data definitions with 1…n. Probably 0…n-1 should be used, but original times control directive defines % as 1-based.
Yes ... I know that Wink I read also this answer.

I'm sorry ... but my English is not very good.
I understand this sentence, but I don't understand the consequences
("consequences" ... "effects brought" .. better in English?)
of this change (between the two definitions)

in memory, the result is identical.
then .. where is the difference? (about the result after compilation)


_________________
I am not young enough to know everything (Oscar Wilde)- Image


Last edited by ouadji on 09 Feb 2010, 19:18; edited 1 time in total
Post 09 Feb 2010, 19:11
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.