ok sorry for 2 topics with almost similair name but this is something different, i have (as you can see from the other topic) the following decleration:
vertex struct

x dword ?
y dword ?
z dword ?
sc_x dword ?
sc_y dword ?
vertex ends

vX struct
vertex 3 dup (<>)
vX ends

triangle struct
v vX <>
visible byte 1
nx byte ?
ny byte ?
nz byte ?
triangle ends

cube triangle 12 dup (<>)

i made some code to fill up kinda like this:

mov cube[0].v[0].x, 10
mov cube[11].v[2].z, 10

now i was wondering how much space it would take up so i opened up my program in a debugger and what did i see, masm compiled my offsets as following:

offset cube[0].v[0].x = Q
offset cube[1].v[0].x = Q + 1
offset cube[10].v[0].x = Q + 10
offset cube[11].v[0].x = Q + 11

why is this???? all vars are kinda overwriting each other when i dont use arrays it goes correct but i need arrays to handle all items in a loop, can anyone clear up why masm does this and how to fix it?

btw, i use QEDITOR form iczelions site (win32asm.cjb.net) for compiling my code
Posted on 2004-11-28 16:17:39 by Scorpie
That's because the [] means how many bytes from the start of the structure is the offset you need, not how many elements as in C.
local array1[200]:DWORD ; allocates 800 bytes ,but:
mov array1[12],eax will write to the 4th element not the thirteenth.
Posted on 2004-11-28 23:16:01 by Ultrano
i am perfectly aware of that information and maybe i explained myself wrong, what i mean to say is that:

mov cube[0].v[0].x, 100h
mov cube[0].v[0].y, 101h

mov cube[1].v[0].x, 200h
mov cube[1].v[0].y, 201h

is executed as following

mov dword ptr ds:[403016], 100h
mov dword ptr ds:[40301A], 101h
mov dword ptr ds:[403017], 200h
mov dword ptr ds:[40301B], 201h

so they really ARE overwriting each other, except for the first byte of the previous item in the array, hope you understand Q in the last post better now (i also calculated the size that it uses for the complete array and its really overwriting)

edit: and sure, i know i should be able to use hexaddresses in my code instead of var names but when structures come as complex as this, the use of var's is a nive option :)
Posted on 2004-11-29 00:10:27 by Scorpie
As Ultrano said, cube[1] is one byte after cube[0]. You have to use the size of an element to calculate the offset :

mov cube[0].v[0].x, 100h
mov cube[0].v[0].y, 101h

mov cube[1*SIZEOF(triangle)].v[0].x, 200h
mov cube[1*SIZEOF(triangle)].v[0].y, 201h
Posted on 2004-11-29 01:32:38 by Dr. Manhattan
yes i know, i didnt make the offset code, MASM compiler did and i want to know why and how i can make a normal array of a structure then without the items of the array overlapping each other
Posted on 2004-11-29 08:27:52 by Scorpie
Afternoon, Scorpie.

Is something wrong with you?

Twice you've been clearly supplied the answer and twice you've said "I know" and then gone onto repeating the question again.

Please re-read the two supplied answers again until you actually understand them.

Posted on 2004-11-29 15:56:23 by Scronty
sorry for my bad english and as i reread the posts it seems that i have missed the info that was given to me, i misunderstood their posts and thought they where only saying what i already mentioned in my posts.
but according to this info, how must i declare my array then?
can i still declare it as i didnt in my first post or do i have to calculate how many items i need to declare to reserve enough space?

(i solved this problem by using a dword array and i calculated the mem offsets in my head instead of using a structure, works fine now but maybe ill rewrite it again to make use of the structure)

anyways, sorry to all who where misunderstood and for my uncarfully reading of the reply's, Scorpie
Posted on 2004-11-29 16:06:37 by Scorpie
Afternoon, Scorpie.

You can declare the array as you've done so and access each element like so:

; Front Face
mov cube[0*SIZEOF(triangle)].v[0*SIZEOF(vertex)].x, -10
mov cube[0*SIZEOF(triangle)].v[0*SIZEOF(vertex)].y, 10
mov cube[0*SIZEOF(triangle)].v[0*SIZEOF(vertex)].z, 10
mov cube[0*SIZEOF(triangle)].v[1*SIZEOF(vertex)].x, -10
mov cube[0*SIZEOF(triangle)].v[1*SIZEOF(vertex)].y, -10
mov cube[0*SIZEOF(triangle)].v[1*SIZEOF(vertex)].z, 10
mov cube[0*SIZEOF(triangle)].v[2*SIZEOF(vertex)].x, 10
mov cube[0*SIZEOF(triangle)].v[2*SIZEOF(vertex)].y, 10
mov cube[0*SIZEOF(triangle)].v[2*SIZEOF(vertex)].z, 10

mov cube[1*SIZEOF(triangle)].v[0*SIZEOF(vertex)].x, -10
mov cube[1*SIZEOF(triangle)].v[0*SIZEOF(vertex)].y, -10
mov cube[1*SIZEOF(triangle)].v[0*SIZEOF(vertex)].z, 10
mov cube[1*SIZEOF(triangle)].v[1*SIZEOF(vertex)].x, 10
mov cube[1*SIZEOF(triangle)].v[1*SIZEOF(vertex)].y, 10
mov cube[1*SIZEOF(triangle)].v[1*SIZEOF(vertex)].z, 10
mov cube[1*SIZEOF(triangle)].v[2*SIZEOF(vertex)].x, 10
mov cube[1*SIZEOF(triangle)].v[2*SIZEOF(vertex)].y, -10
mov cube[1*SIZEOF(triangle)].v[2*SIZEOF(vertex)].z, 10

; Back Face

Posted on 2004-11-29 16:43:11 by Scronty
That will work where sizeof triangle and sizeof vertex are a multiple of 2.
What if they are not? You can use registers to offset :)

mov ebx,sizeof (triangle)
mov eax, sizeof (vertex)
mov cube[0*ebx].v[0*eax].x, -10
mov cube[0*ebx].v[0*eax].y, 10
...etc , replacing the 0 with the array index (element#)
Posted on 2004-11-29 17:36:37 by Homer
nope, it will run always no matter the size of those structures.
mov cube[1*SIZEOF(triangle)].v[1*SIZEOF(vertex)].x, -10
if cube is at offset 10000d, the above will get translated to:

mov dword ptr[10000 + 64 + 20 + 0],-10
64 = size of triangle
20 = size of vertex
0 = offset of vertex.x

if "triangle" was 49 bytes, this would look like:
mov dword ptr[10000 + 49 + 20 + 0],-10
nothing illegal here to the instruction set. Remember it's static data we're talking about :)
Posted on 2004-11-29 17:50:26 by Ultrano
I wish I could point you to my tutorial in the phpwiki book, but at the moment it doesn't appear to be available.

Neither MASM nor the CPU will create the appropriate nonoverlapping array offset for you. You must add extra code to create the correct offset.

The following is what you must do if you are going to hold the subscripts in registers (for looping).


To simplify things, I am going to assume a lower array bound of 0.

For a one-dimension array, it is simply a matter of multiplying by the size (in bytes) of the array element.

If the size is a single byte (for example, ASCII characters), you don't need to do anything special.

If it's an odd size, you will need to use a multiply instruction.
    mul   ecx,ecx,sizeof_element  ; sizeof_element must be a constant

mov eax,array[ecx] ; get element
mov array[ecx],eax ; store element

If the size is 2, 4, or 8, you can use a scaling factor.
    mov   eax,array[ecx*4]  ; get element

mov array[ecx*4],eax ; store element


Now for the more complex multidimensioned arrays.
I will show how offsets for three dimensions are calculated. It's up to you to create the code to create the offset.

size1 = data size
size2 = size1 * dimension1
size3 = size2 * dimension2

offset of arr = (subscript3 * size3) + (subscript2 * size2) + (subscript1 * size1)


For loops, there is an optimization where the +1 subscript increments are replaced by size-n offset increments.
Posted on 2004-11-30 00:02:55 by tenkey