Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Declaring 3d array using new/typedef.

Credits go to Oscar Giner and William Labbett for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
Declaring 3d array using new/typedef.
verthex
Member #11,340
September 2009
avatar

OnlineCop said:

This basically calls the "real" main() function after allocating 0x30 bytes (48 bytes) on the stack.

Its that the actual array I declared, I don't think 48 bytes equal 10 ints. Not sure how much an int is now. I know a word is 4 bytes.

Arthur Kalliokoski
Member #5,540
February 2005
avatar

4 bytes to save ebp, 4 bytes for the return address of whatever called the code (?), plus 10 ints at 4 bytes each = 48.

I really admire the U.S. Constitution. It's so much better than what we have now.

verthex
Member #11,340
September 2009
avatar

4 bytes to save ebp

I'm guessing that the array is created on the stack and the ebp stores the location pointer to it?

someone972
Member #7,719
August 2006
avatar

Ebp is the base of the stack when the function was called, so that the stack can just be popped back to that position when the function returns. It is also used to address all variables allocated on the stack in that function. The array is addressed by ebp plus some offset, so to move a number into one of the array locations it would be something like this:

mov [ebp+0h], eax //same as moving  the contents of eax into array[0]
mov [ebp+4h], eax //same as moving the contents of eax into array[1]

This is assuming that the array starts at ebp, if other variables were to be declared then a bigger offset would be required.

EDIT: I'm not certain, but I think this is also why declaring variable sized arrays on the stack requires some black magic from compilers, since it can no longer have a set offset for the variables.

______________________________________
As long as it remains classified how long it took me to make I'll be deemed a computer game genius. - William Labbett
Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why. -Unknown

verthex
Member #11,340
September 2009
avatar

mov [ebp+0h], eax //same as moving the contents of eax into array[0]
mov [ebp+4h], eax //same as moving the contents of eax into array[1]

How would this work for more than one dimension?

someone972
Member #7,719
August 2006
avatar

I'm not going to try and write the assembly for it, but you would basically move the first index into a register, multiply it by the length of one of the dimensions, then add the offset for the second dimension and then add it to ebp. Remember that the stack is one dimensional, so every array has to be "flattened" and then indexed in this way.

______________________________________
As long as it remains classified how long it took me to make I'll be deemed a computer game genius. - William Labbett
Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why. -Unknown

Arthur Kalliokoski
Member #5,540
February 2005
avatar

Depending on the array dimensions, you can multiply by powers of two up to 32 (?) and add registers and a constant together. ex. mov eax,[ebx*4+ebp+16] I used to also have seperate segments in DOS so I could specify different segment registers for an additional dimension (although you couldn't use multiplication).

I really admire the U.S. Constitution. It's so much better than what we have now.

verthex
Member #11,340
September 2009
avatar

I'm not going to try and write the assembly for it, but you would basically move the first index into a register, multiply it by the length of one of the dimensions, then add the offset for the second dimension and then add it to ebp. Remember that the stack is one dimensional, so every array has to be "flattened" and then indexed in this way.

I wonder if this is the actual answer, which is basically looks like yours but explained with C.

Depending on the array dimensions, you can multiply by powers of two up to 32 (?) and add registers and a constant together. ex. mov eax,[ebx*4+ebp+16] I used to also have seperate segments in DOS so I could specify different segment registers for an additional dimension (although you couldn't use multiplication).

Is that related to the row major order method?

I'm wondering if maybe you had more code on that btw? Or a link?

Arthur Kalliokoski
Member #5,540
February 2005
avatar

verthex said:

I'm wondering if maybe you had more code on that btw? Or a link?

No, I'd have to google for it just like you would. OTOH, for a 2D array, it's not hard at all. Remember mode 19 in DOS? It had 200 rows that were 320 bytes long.

_setpixel: proc near  ;32 bit C prototype void setpixel(x,y);
 mov eax,[esp+8] ;y
 mov edx,[esp+4] ;x
 imul eax,320
 add edx,[_bufferstart]  ;near pointer to 0xA0000 where screen memory for mode 19 is (flat memory)
 add edx,eax
 mov al,[_color]  ;color is a global
 mov [edx],al
 ret

Notice you don't have to fiddle with ebp in 32 or 64 bit modes.

I really admire the U.S. Constitution. It's so much better than what we have now.

verthex
Member #11,340
September 2009
avatar

Remember mode 19 in DOS?

Oh mode 13h, there is Michael Abrashs black book on it, but I'm not sure he ever covers 3d either.

Quote:

[_bufferstart] ;near pointer to 0xA0000

So bufferstart = 0xA0000?

I did fiddle with this stuff maybe 8 years ago writing to the ports for modex and then gave up since there was nothing useful in it that couldn't be coded easier with C++; hence allegro ~4, which is what I did try soon after reading that book. And directx9.

Arthur Kalliokoski
Member #5,540
February 2005
avatar

verthex said:

Oh mode 13h, there is Michael Abrashs black book on it, but I'm not sure he ever covers 3d either.

There's lots of 3D and Quake stuff in there if you look.

Quote:

So bufferstart = 0xA0000?

In DOS with a flat zero based memory compiler such as Watcom.

My point about mode 13h was more to show how to access a 2D array than how to do graphics.

I really admire the U.S. Constitution. It's so much better than what we have now.

verthex
Member #11,340
September 2009
avatar

There's lots of 3D and Quake stuff in there if you look.

Right but not a 3d array. It covers the methods for drawing polygons and clipping.

Quote:

My point about mode 13h was more to show how to access a 2D array than how to do graphics.

Sorry for going off topic there, its a tendency to wander.

EDIT:

Check out the link under sample three dimensional array.

I guess its in HLA: MASM with link16.

#SelectExpand
1; Multidimensional Array declaration and access 2; 3; Randall Hyde 4 5 6 .386 ;Need these two statements to 7 option segment:use16 ; use the 80386 register set. 8 9 10dseg segment para public 'data' 11 12 13; Indices we will use for the arrays. 14 15J word 1 16K word 2 17L word 3 18 19; Some two-dimensional arrays. 20; Note how this code uses the "dup" operator to suggest the size 21; of each dimension. 22 23B2Ary byte 3 dup (4 dup (?)) 24W2Ary word 4 dup (3 dup (?)) 25D2Ary dword 2 dup (6 dup (?)) 26 27 28 29; 2D arrays with initialization. 30; Note the use of data layout to suggest the sizes of each array. 31 32B2Ary2 byte 0, 1, 2, 3 33 byte 4, 5, 6, 7 34 byte 8, 9, 10, 11 35 36W2Ary2 word 0, 1, 2 37 word 3, 4, 5 38 word 6, 7, 8 39 word 9, 10, 11 40 41D2Ary2 dword 0, 1, 2, 3, 4, 5 42 dword 6, 7, 8, 9, 10, 11 43 44; A sample three dimensional array. 45 46W3Ary word 2 dup (3 dup (4 dup (?))) 47 48dseg ends 49 50 51cseg segment para public 'code' 52 assume cs:cseg, ds:dseg 53 54Main proc 55 mov ax, dseg ;These statements are provided by 56 mov ds, ax ; shell.asm to initialize the 57 mov es, ax ; segment register. 58 59; AL := B2Ary2[j,k] 60 61 mov bx, J ;index := (j*4+k) 62 add bx, bx ;j*2 63 add bx, bx ;j*4 64 add bx, K ;j*4+k 65 mov al, B2Ary2[bx] 66 67 68; AX := W2Ary2[j,k] 69 70 mov ax, J ;index := (j*3 + k)*2 71 mov bx, 3 72 mul bx ;(j*3)-- This destroys DX! 73 add ax, k ;(j*3+k) 74 add ax, ax ;(j*3+k)*2 75 mov bx, ax 76 mov ax, W2Ary2[bx] 77 78 79; EAX := D2Ary[i,j] 80 81 mov ax, J ;index := (j*6 + k)*4 82 mov bx, 6 83 mul bx ;DX:AX := j*6, ignore overflow in DX. 84 add ax, k ;j*6 + k 85 add ax, ax ;(j*6 + k)*2 86 add ax, ax ;(j*6 + k)*4 87 mov bx, ax 88 mov eax, D2Ary[bx] 89 90 91; Sample access of a three dimensional array. 92; 93; AX := W3Ary[J,K,L] 94 95 mov ax, J ;index := ((j*3 + k)*4 + l)*2 96 mov bx, 3 97 mul bx ;j*3 98 add ax, K ;j*3 + k 99 add ax, ax ;(j*3 + k)*2 100 add ax, ax ;(j*3 + k)*4 101 add ax, l ;(j*3 + k)*4 + l 102 add ax, ax ;((j*3 + k)*4 + l)*2 103 mov bx, ax 104 mov ax, W3Ary[bx] 105 106 107Quit: mov ah, 4ch ;Magic number for DOS 108 int 21h ; to tell this program to quit. 109Main endp 110 111cseg ends 112 113sseg segment para stack 'stack' 114stk byte 1024 dup ("stack ") 115sseg ends 116 117zzzzzzseg segment para public 'zzzzzz' 118LastBytes byte 16 dup (?) 119zzzzzzseg ends 120 end Main

 1   2 


Go to: