Author Topic: Repeating a Structure  (Read 22235 times)

Offline cmclaughlan

  • Jr. Member
  • *
  • Posts: 2
Repeating a Structure
« on: October 23, 2010, 01:05:04 AM »
What is the proper way to repeat a data structure ?

I define my structure and then use:
Code: [Select]
my_texture0 istruc TextureImage ; one instance of the structure
iend

But what am I supposed to do if I want 50 structures ?

Right now I'm using:

Code: [Select]
NumTextures                              50
my_texture_block
%rep NumTextures
istruc TextureImage
iend
%endrep

But I was wondering if there was a recommended way of doing it.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Repeating a Structure
« Reply #1 on: October 23, 2010, 02:12:13 AM »
That's probably how I would do it if I wanted them initialized. For example:

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

SECTION .data
myPoints:
%rep 50
ISTRUC Point
AT Point.x,  DB 3
AT Point.y,  DB 2
AT Point.z,  DB 1
IEND
%endrep

All 50 Points are initialized with the values P(3,2,1). However, if I really didn't care what the values were, or I was just initializing to zero, then I would probably use TIMES or RESB like so:

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

SECTION .data
dsPoints: TIMES (50 * Point_size) DB 0

SECTION .bss
bsPoints: RESB (50 * Point_size)

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Repeating a Structure
« Reply #2 on: October 23, 2010, 09:28:57 AM »
One very minor nit:

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

SECTION .data
myPoints:
%rep 50
ISTRUC Point
AT Point.x,  DB 3
AT Point.y,  DB 2
AT Point.z,  DB 1
IEND
%endrep

You've defined the elements/members of "Point" as "DD", and initialized them as "DB". I don't think that'll do any harm, but it "looks funny". Might be worth mentioning that we don't have to initialize all the elements. We could do:

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

SECTION .data
myPoints:
%rep 50
ISTRUC Point
AT Point.x,  DD 3
AT Point.z,  DD 1
IEND
%endrep

And all the "Point.y"s would be initialized/padded to zero. The elements we do initialize have to be "in order" as we've declared 'em, but they don't all have to be present. This is probably more confusing to the reader of the code than it is useful, but we can do it. (this is why I don't think it'll do any harm to call 'em "DB").

In cases where we're using "Point_size" (or "TextureImage_size" - Nasm calculates "_size" even if we don't explicitly define it), the size is in bytes, so DB or RESB would be correct in that case.

Seems to me that where the "%rep" mechanism would be especially powerful is if we wanted 50 points (or textures) initialized according to a "formula"...

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

SECTION .data
myPoints:

%assign %%xpoint 0
%assign %%ypoint 0
%assign %%zpoint 0

%rep 50
ISTRUC Point
AT Point.x,  DD %%xpoint
AT Point.y,  DB %%ypoint
AT Point.z,  DB %%zpoint
IEND

%assign %%xpoint %%xpoint + 1
%assign %%ypoint %%ypoint + 2
%assign %%zpoint %%zpoint + 3

%endrep

Mmmm... I guess that would have to be in a macro to actually work... something like this?

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

%macro thepoints 0

%assign %%xpoint 0
%assign %%ypoint 0
%assign %%zpoint 0

%rep 50
ISTRUC Point
AT Point.x,  DD %%xpoint
AT Point.y,  DB %%ypoint
AT Point.z,  DB %%zpoint
IEND

%assign %%xpoint %%xpoint + 1
%assign %%ypoint %%ypoint + 2
%assign %%zpoint %%zpoint + 3

%endrep
%endmacro

SECTION .data
myPoints: thepoints

If we don't need 'em initialized, I like Bryant's:

Code: [Select]
SECTION .bss
bsPoints: RESB (50 * Point_size)

Although ".bss" is nominally "uninitialized", it is in fact initialized to zeros (in any sane output format - not true for a .com file). Another option, if we wanted 'em initialized to non-zero, but all the same (very rarely useful, I would think)...

Code: [Select]
section .data
mypoints times 50 DD 1, 2, 3

(this gets away from the "struc" mechanism - probably less clear)

So there are different ways to do it - "%rep"/"%endrep" probably being the most flexible. Might be "overkill" in this case, but it should work fine.

Best,
Frank


Offline cmclaughlan

  • Jr. Member
  • *
  • Posts: 2
Re: Repeating a Structure
« Reply #3 on: October 24, 2010, 12:44:16 PM »
Thanks for your great feedback Bryan and Frank.

It was the TIMES I really wanted (so I could have them unititialized).
And I appreciate the hint about the "_size" ! My code is littered with
Code: [Select]
headerlen equ $-header

and that will help me tidy that all up (and not have to remember to set it for every structure I need the _size of)

Cheers,

Colin

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Repeating a Structure
« Reply #4 on: October 24, 2010, 10:47:07 PM »
One very minor nit:

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

SECTION .data
myPoints:
%rep 50
ISTRUC Point
AT Point.x,  DB 3
AT Point.y,  DB 2
AT Point.z,  DB 1
IEND
%endrep

You've defined the elements/members of "Point" as "DD", and initialized them as "DB". I don't think that'll do any harm, but it "looks funny". Might be worth mentioning that we don't have to initialize all the elements. We could do:

Code: [Select]
STRUC Point
.x RESD 1
.y RESD 1
.z RESD 1
ENDSTRUC

SECTION .data
myPoints:
%rep 50
ISTRUC Point
AT Point.x,  DD 3
AT Point.z,  DD 1
IEND
%endrep

Yeah, totally a typing (mental) error. Not sure why I put DB other than I was just throwing up a quick response and failed to pay attention to what I was posting. :P As for whether it matters or not, yeah it does because once you start accessing data out of the structure the user will expect the data to be dword's and will access them as dwords, so say you store 0xAAAAAAAA in Point.x then put 0xFFFFFFFF in Point.y, then later return to access Point.x again, it wouldn't be the same as what they expected it to be. Nah, that was totally a foul up on my behalf.

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Repeating a Structure
« Reply #5 on: October 25, 2010, 12:04:42 AM »
Funny thing is, after calling you on it, I did the same thing in my examples!

Code: [Select]
...
%rep 50
ISTRUC Point
AT Point.x,  DD %%xpoint
AT Point.y,  DB %%ypoint
AT Point.z,  DB %%zpoint
IEND
...

Changed "Point.x", but missed ".y" and ".z."! An easy mistake to make, apparently! :)

Anyway... they should match... By rights, maybe Nasm should throw an error there, but it doesn't...

Best,
Frank


Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 429
  • Country: us
Re: Repeating a Structure
« Reply #6 on: October 25, 2010, 02:21:13 AM »
As an aside, the NASMX_ISTRUC macros were designed to prevent those particular typo errors from occuring  ;)