Unit 6.7 -- 2-D Array, Constant Subscript, Ranges starting at zero PROG Move some data around a two-dimensional array PED learn how to access two dimensional arrays with constant subscripts and with both ranges starting at zero CONCEPT Given the following array A A:array[0..m,0..n] of integer; A(i,j) can be found in memory location A+(i*(n+1)+j)*4 Two dimensional arrays are stored row by row so the second subscript varies most rapidly. 18.html Unit 6.7 2-D array, constant subscript, ranges starting at zero In unit 6.6, we learned how to handle 2-D arrays. They are stored in memory with the first row laid out sequentially in memory. After the last word in the first row appears in memory comes the first word of the second row. And likewise, after the last word of the second row appears in memory, comes the first word of the third row appears. And the last word would be the last word in the last memory. As we did with stored one-dimensional arrays, we will first discuss how to deal with constant subscripts. We can refer to A(i,j) in a single line when i and j are both constants. And like before, we will discuss the case where the ranges are both zero. The next unit will discuss what happens when the ranges are not both zero. We will see that there are three frequent methods of processing two-dimensional arrays. The first two cover situations where one covers the array, row by row. I.E., wsequentially process all the elements in the first row, the all the elements in the second row, then all the elements in the third row up to doing all the elements in the last row. The last example covers a situation where one process all the elements in the first column, then all the elements in the second column, all the way up to doing all the elements in the last column. These two types of codes cover most of the applications of 2-D arrays in practice. Obviously, there are some programming applications where one might go through the I,J-pairs randomly, by diagonals, etc. These are covered as exercises for the interested reader. For an array declared: array[0..m,0..n] of integer; the form A+(i*(n+1)+j)*4 gives the address of element I,J. "(n+1)" represents the fact that there are n+1 integers in each row. We multiply that by the row number, i. This now gives us the offset of the first element in the ith row from the beginning of the array in integers. The next thing to do is add j. This is the offset of the item wanted from the beginning of the array--in integers. Multiplying by four gives us the offset of the item wanted from the beginning of the array--in bytes. This offset is added to "A" or the address of the beginning of the array. In our example program, we have an array that is declared [0..5,0..5]. That means m and n are both five. Our array looks like--remember that the array A begins at 40 hex: 0,0 0,1 0,2 0,3 0,4 0,5 20040 20044 20048 2004C 20050 20054 1,0 1,1 1,2 1,3 1,4 1,5 20058 2005C 20060 20064 20068 2006C 2,0 2,1 2,2 2,3 2,4 2,5 20070 20074 20078 2007C 20080 20084 3,0 3,1 3,2 3,3 3,4 3,5 20088 2008C 20090 20094 20098 2009C 4,0 4,1 4,2 4,3 4,4 4,5 200A0 200A4 200A8 200AC 200B0 200B4 5,1 5,1 5,2 5,3 5,4 5,5 200B8 200B8 200BC 200C0 200C4 200C8 We now examine the program, and observe that applying the above formula gets the correct location for each subscript. The first statement to be translated is: A[2,2]:=1; (Line 9 gets one in register one.) Line 10 does the store into A[2,2]. We substitute into our formula: A[i,j] is at address A+(i*(n+1)+j)*4. This leaves us with doing a store to location: A+(2*6+2). n+1= 5+1; This creates the 6 in the formula. i is 2 creating the first "two" "j" is also 2 creating the second 2. Substituting 20040 for A, we determine that the address is 20078 hex. Looking at the diagram above, we find that this in fact the address of A[2,2]. Next is A[3,2]:=2; i is 3, j is 2 and n is still 5. This gives us the A+(3*6+2)*4 in line 13. Substituting 20040 for A, we get a location of 20090. Observe this appears in the ADDR2 column of line 13. The next statement to convert is A[4,1]:=3 i is 4, j is 1. Substituting into the formula gives us A+(4*6+1)*4. Substituting 20040 for A, we get a location of 200A4. Observe this appears in the ADDR2 column of line 16. The last simple assignment statement is A(5,1):=6. i is 5, j is 1. This gives us A+(5*6+1)*4. Substituting 20040 for A, we get a location of 200BC. Note that this appears in line 19 of ADDR2 column. The last statement is A(5,2):=A(4,1)+A(5,1) Just as for the familiar expression, C:=A+B, we load the first item to be summed into a register, add the second item to be summed to that register and lastly, store that register in that third item. In this case, the first item to be summed, and, hence, loaded into a register is A(4,1). Line 21 performs this load. Note the 200A4 in the ADDR2 column of line 21. Then we add A(5,1). Note here the 200BC address of this item. And, lastly, we store this in A(5,2). i is 5 and j is 2 giving us A+(5*6+2)*4 for this quantity. This works out to address 200C0 to store into. Note the 000C0 in the ADDR2 column.