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.