Unit  6.8  --  2-D  Array,  Constant  Subscript,  Range  not
starting at Zero

PROG

Move some data around in a two dimensional array

PED

learn how to access two dimensional arrays with
constant subscripts and with
neither range starting at zero

CONCEPTS

Given the following array A

A: array[k:m,x:n] of integer;

A(i,j) is at

A+((i-k)*(n-x+1)+(j-x))*4


SF

none

19.html


Unit 6.8 -- 2-D array, constant subscript, range not starting at
zero

In  this  unit,  we  learn how to deal with  two-dimensional
arrays where the ranges do not necessarily begin with  zero.
Notice that in this unit, the subscripts, i and j in A[i,j],
are still constant!

Let   us   assume   that   we   have   an   array   declared
A:array[k:m,x:n] of integer.

As  in  the  last  example,  A(i,j)  in  an  array  declared
[0..m,0..n].  we took the offset in rows from the  beginning
and  multiply that by the number of integers in a row.  This
gave  us  the  offset  of  the beginning  of  the  row  from
beginning  of array.  In unit 22, that led to the expression
i*(n+1).  Here, it is more complicated.  The offset in  rows
is  i.   The number of integers in a row was n+1.   We  then
added  j  which  was  the offset of  the  element  from  the
beginning of the row--in integers.  This gave us i*(n+1)+j.

We  multiplied the whole thing by 4 to get the offset of the
element  from  the beginning of A--in integers.    And  then
this was added to A to get the address of A[i,j]--giving  us
the familiar expression
A+(i*(n+1)+j)*4.

Let  us apply the same logic to developing an expression for
the  general case for a two-dimensional array whose   ranges
do not begin with zero.

In the case, A:[k:m,x:n] of integer;

The address of A[i,j] in this array is
A+((i-k)*(n-x+1)+(j-x))*4

The  number  of integers in a row is n-x+1.  The  number  of
rows  from he beginning of the array is i-k.  Thus, we  have
the expression (i-k)*(n-x+1).  Then we add the offset of the
element  from the beginning of the row containing it.   This
is  (j-x).  And, of course, this is in integers so the whole
kit and caboodle gets multiplied by four before adding it to
the beginning of the array.

Let's look at our example.  We have an array dimensioned:
    [4..7,3..10] of integer;
k is 4
m is 7
x is 3
n is 10  -- in the formula above.

That  means the number of integers in a row, (n-x+1) is  8--
(10-3+1).

Note that A is located again at 20040.  There are a total of
four rows, each with eight elements so we have to declare 32
empty spaces for our stuff.

The layout is as follows:

 4,3    4,4   4,5   4,6   4,7   4,8   4,9  4,10
20040  20044 20048 2004C 20050 20054 20058 2005C

 5,3    5,4   5,5   5,6   5,7   5,8   5,9  5,10
20060  20064 20068 2006C 20070 20074 20078 2007C

 6,3    6,4   6,5   6,6   6,7   6,8   6,9  6,10
20080  20084 20088 2008C 20090 20094 20098 2009C

 7,3    7,4   7,5   7,6   7,7   7,8   7,9  7,10
200A0  200A4 200A8 200AC 200B0 200B4 200B8 200BC

The first PASCAL to convert is:
A[4,9]:=1

We load 1 into a register.
i becomes 4 and j becomes 9, resulting in
A+((4-4)*8+(9-3))*4 as the address of  A[4,9].   This  works
out  to  58  hex.   Note about that this is the  address  of
A[4,9] and the 58 in the ADDR2 of line 10.

The next PASCAL to convert is:
A[6,9]:=3.
i is 6 and j becomes 9 resulting in:
A+((6-4)*8+(9-3))*4.  This works out to 20098 hex.  Note  in
the  chart above that a[6,9] can be found at 20098, and  the
98 in ADDR2 of line 13.

The next PASCAL to convert is:
A[7,3]:=6.
i is 7 and j becomes 3 resulting in:
A+((7-4)*8+(3-3))*4.  This works out to 200A0 hex.  Note  in
the  chart above that a[7,3] can be found at 200A0, and  the
A0 in ADDR2 of line 16.

The next PASCAL to convert is:
A[5,6]:=12.
i is 5 and j becomes 6 resulting in:
A+((5-4)*8+(6-3))*4.  This works out to 2006C hex.  Note  in
the  chart above that a[5,4] can be found at 2006C, and  the
6C in ADDR2 of line 19.

Now  we  do  the addition of A(5,6) and A(7,3)  putting  the
result  in  A(5,7).  As before we load A(5,6) into  register
one.   We then add A(7,3).  And finally the result goes into
A(5,7).

In  line  21, we load up A(5,6).  Note that we use the  same
address-expression as in line 19 and again the ADDR2 line is
6C.

In  line  22,  we  add  A(7,3).  We  use  the  same  address
expression as in line 16 and again the ADDR2 line is A0.

Finally,  we  store in A(5,7).  Here i is  5  and  j  is  7,
resulting  in  the address expression A+((5-4)*8+7)*4  which
works out to 70 hex.  Note that 20070 is A(5,7) in the chart
above and the 70 in ADDR2 column of line 23.