|
|
This thread is locked; no one can reply to it.
|
1
2
|
| Declaring 3d array using new/typedef. |
|
verthex
Member #11,340
September 2009
|
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
|
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
|
Arthur Kalliokoski said: 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
|
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. ______________________________________ |
|
verthex
Member #11,340
September 2009
|
someone972 said: mov [ebp+0h], eax //same as moving the contents of eax into array[0] How would this work for more than one dimension?
|
|
someone972
Member #7,719
August 2006
|
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. ______________________________________ |
|
Arthur Kalliokoski
Member #5,540
February 2005
|
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
|
someone972 said: 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. Arthur Kalliokoski said: 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
|
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
|
Arthur Kalliokoski said: 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
|
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
|
Arthur Kalliokoski said: 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 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
|