Can someone please show me the proper syntax for declaring a multidimensional array in Masm. (before i kill my cat)

lets say a 3 times 2 times 2 array with some values already put in

syntax is not my strongest suit

Thanx a gig
:confused:
Posted on 2001-08-25 14:13:24 by titan
Its not too hard to reserve the memory, a 3*2*2 uninitalised array would be:

.data?
Array dd 3*2*2 dup (?)

or

Array dd 3 dup ( 2 dup ( 2 dup (?) ) )

The problem is access and its very difficult for all but 2d arrays. Take a 2d array of 5*6. Here is how you access the elements

(0,0) = [0]
(1,0) = [1]
(3,0) = [3]
(0,1) = [5]
(0,2) = [10]
(2,2) = [12]

the general formula of an w*h array is:

(x,y) =

This formula is scalable to higher dimensions, eg w*h*d array

(x,y,z) =

Remember each of these offsets should be scaled by the data size.
Posted on 2001-08-25 17:04:58 by Eóin
I think it's not hard to write a macro that returns the right offset on a given array, problem is that you either have to specify the size of each dimension every time you use the macro, or just once but this has complications if you use multiple multidimension arrays..
Don't have time for the macro right now though.
Thomas
Posted on 2001-08-25 17:18:19 by Thomas
Look like there is an oportunity for a macro here: :alright:
;Multi-dimentional array indexing

Item MACRO array:REQ,vars:VARARG
LOCAL flag,count,total
flag = 1
count = 0
total = 1
FOR var,<&vars>
IF flag EQ 0
total = total * var
flag = 1
ELSE
total = total * TYPE &array
count = count + var * total
flag = 0
ENDIF
ENDM

EXITM @CatStr(<&array>,< + >,<&count>)
ENDM

.data?

MyArray dd 5*7*6 dup (?)

.code
mov eax,Item(MyArray,<3,5>,<4,7>,<2,6>)
First item is the name of the array. Then there are a series of pairs (an array if you will :)): <index, size of dimension>. index is between [0,size of dimension). size of dimension is 1 or greater. For example, in the above example, you would get the last item with:

mov eax,Item(MyArray,<4,5>,<6,7>,<5,6>)

...and the first item is:

mov eax,Item(MyArray,<0,5>,<0,7>,<0,6>)

One of the things I don't like about MASM macro lanugage is that parses out the brackets. There are other ways to pass multi-dimensional arrays to macros, but with the line length limit, it's hardly useful. So, anyway, you can do:

mov eax,Item(MyArray,4,5,6,7,5,6)

...but that is so unreadable. The macro handles arrays of other types, too. Enjoy!

Edit: I think I've fixed it - it wasn't right before. :tongue:
Posted on 2001-08-25 19:02:53 by bitRAKE
I couldn't sleep, and came up with this. Let me know if it works?


;* @ArgI - Macro function returns an argument specified by number
;* from a VARARG list.
;*
;* Params: index - one-based number of the argument to be returned
;* arglist - argument list
@ArgI MACRO index:REQ, arglist:VARARG
LOCAL count,retstr
count = 0
FOR arg,<arglist>
count = count + 1
IF count EQ index
retstr TEXTEQU <arg>
ENDIF
ENDM
EXITM retstr
ENDM


MakeArray MACRO thename:REQ,thetype:REQ,vars:VARARG
LOCAL elements

;Figure out the total number of elements
elements TEXTEQU <1>
FOR var,<&vars>
elements CATSTR %elements,<*>,%var
ENDM

;Create the Array
_BSS segment DWORD public 'BSS'
thename LABEL thetype
;; Get a warning for standard data types in BSS, but works for all
thetype elements dup (<?>)
; thetype elements dup (?)
_BSS ends

;Create the indexing macro
thename&Item MACRO args:VARARG
LOCAL count,dwidth,dist

count = 0
dwidth = 1
dist = 0

FOR arg,<&args>
count = count + 1
dist = dist + (arg * dwidth)
dwidth = dwidth * @ArgI(%count,vars)
ENDM
dist = dist * TYPE thename
EXITM @CatStr(<thename>,<+>,%dist)

ENDM
ENDM


MakeArray MyArray,DWORD,5,7,6

mov eax,MyArrayItem(0,0,0)
mov eax,MyArrayItem(1,0,0)
mov eax,MyArrayItem(2,0,0)
mov eax,MyArrayItem(4,6,5)

;Why would there be any problems with objects in ASM ;)
MakeArray StrangeOne,RECT,5,2,4

mov eax,[StrangeOneItem(3,1,1)].right
This is very flexible and easy to use! :alright:
Sorry Thomas, I took your message for a challenge. :) Posted on 2001-08-26 02:59:50 by bitRAKE
I can't test it on the computer I'm working on now but it looks fine, well done.:alright:
Maybe a nice code snippet for APJ (See this thread)?

Thomas
Posted on 2001-08-26 03:26:55 by Thomas
Actually, I was thinking about creating an array class with macros that allows static/dynamic access/allocation. Support something like this in addition to what we already have:

MakeArray(MyArray,RECT,10,30,eax)

mov eax,MyArrayItem(0,eax,ecx)

That would be very cool. I wonder what kind of coding problems I'm going to create with this? :) Before I wondered why I didn't see anyone else using macros in macros? Then I saw a paragraph of the MASM manual that states macros in macros are only usable inside those macros. Their own example goes against this! I don't know who wrote the manual, but it wan't anyone on the programming team. :tongue:

Implementing sorting would be good, too. MyArraySort, but the programmer would have to supply a CompareRECT, CompareDWORD, etc. What other stuff might be good?

Oh, I forgot to say: titan, kill the cat. :alright:
Posted on 2001-08-26 16:17:13 by bitRAKE
titan, to answer your original question:

MyArray dd \
1,2,3,
1,2,3,
\
3,2,1,
3,2,1

The \ keeps the assembler looking beyond the blank line - just there for readablity. That's a 3x2x2 array with data - nothing special. If you wanted to be more verbose, you could create structures and then put data in a named array structure:

xLength STRUC
l0 dd ?
l1 dd ?
l2 dd ?
xLength ENDS

xHeight STRUC
h0 xLength < >
h1 xLength < >
xHeight ENDS

xWidth STRUC
w0 xHeight < >
w1 xHeight < >
xWidth ENDS

MyArray xWidth \
{ \
{ \
{1,2,3},
{3,2,1} \
},
{ \
{6,5,4},
{4,5,6} \
} \
}

This is the cool part - it is accessed like this:

mov eax,MyArray.w0.h0.l0 ;note the order

This quickly gets pretty strange. But with more complex types, this wrapping provides a little protection from dumb errors. :) Look at Chapter 5 - MASM Programmers Manual (hiro, thanks for turning nbsp; off!)
Posted on 2001-08-26 17:22:36 by bitRAKE
Thanx a gig to all who replied.

I copy and paste most replies for future reference.

Better than sifting through the bundle of documentation on a hundred languages and IDEs.

Good Community

And growing rather rapidly i see. :alright:
Posted on 2001-08-26 18:56:25 by titan
There is an error in the macro. I multiply by the size of the items for each dimension of the array - this needs to be moved outside the loop, before the EXITM. And the line changed to:
    dist = dist * TYPE thename
I'm working on an example program and some more flexiblity for this macro - I'll upload it when I'm done. This is what the resulting code should look like:
	FOR arg,<&args>

count = count + 1
dist = dist + (arg * dwidth)
dwidth = dwidth * @ArgI(%count,vars)
ENDM
dist = dist * TYPE thename
EXITM @CatStr(<thename>,<+>,%dist)
Sorry, I can't change the above messages. :(
Posted on 2001-08-27 07:55:23 by bitRAKE
hello,

why don't you use memory on the heap?

with:

.data
hArray  dd ?

invoke GetProcessHeap
invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,(X x Y x Z) * 4
mov hArray,eax

you get the heapspace for your array in bytes with (X x Y x Z) * 4 where x,y,z are the array dimensions.
When you want to access item you have to calculate the pointer to that item on the heap.

After the array may be disbanded use
invoke HeapFree,eax
hope this is helpfull even after several months
Posted on 2005-12-27 02:47:21 by raidu
Hi all
In the objects directory of the ObjAsm32 package is an object called "Array" which is a multidimensional array. The object provides all methods to initialize dispose and access the individual members of the array. The "Array" object is the ancestor of the "Matrix" object witch is widely used for mathematics.

Regards,

Biterider
Posted on 2005-12-27 05:39:08 by Biterider