Unit 6.3 1-D array, non-constant subscript

In  this example, we learn how to deal with cases where  the
subscript is an expression, such as
  a[I]
  A[I+J]
  A[A[i]]

When,  we see something of the form A[expr], we need to  get
to the address:  address of A + expr*4
Since,  expr is not constant, i.e., it's value is not  known
before  we  start running the program, we must do this  with
assembler instructions.

The   procedure   to  retrieve  something  from   array-name
expression is as follows:

1) get address of array-name into regA    LA regA,array-name
2) get the value of expression into regB  L regB,expr
                                          if expr is a variable
3) compute 4*expression                   AR regB,regB
                                          AR regB,regB
4) add 4*expression to address            AR regA,regB
5) fetch the value into regC              L  regC,0(0,regA)

We could also have used an A, S, C or similar instruction in
step 5, rather than just loading the value.

Doing  a store of "something" into array-name(expr)  can  be
done  using the same coding sequence, except instead of step
five, we retrieve the value and do a store.

1) get address of array-name into regA    LA regA,array-name
2) get the value of expression into regB  L regB,expr
                                          if expr is a variable
3) compute 4*expression                   AR regB,regB
                                          AR regB,regB
4) add 4*expression to address            AR regA,regB
5) get the value of "something" in regC   L regC,something
                                          if "something" is a variable
5a) store it into array-name(expr)        ST regC,0(regA)

It  is  now  important  to understand  our  two  new  syntax
features,  the  "LA"  (load  address)  instruction  and  the
"offset(regD,regE)" method of writing memory locations.

For  the  sake of example, assume that the array "A"  is  at
memory  location  20040  and  that  memory  location   20040
contains the integer, 5.

   LA 1,A
will cause the value 20040 to be put into register one.

(Contrast  L  1,A which will cause register one  to  contain
five, the contents of memory location 20040.)

If we then go ahead and write

   L 2,0(0,1)
that   will  fetch  the  contents  of  the  memory  location
indicated  by register one, in other words, the contents  of
memory location 20040.  This will put 5 into register two.

Thus, one could write

    LA 1,blah
    L 1,0(0,1)

instead of
    L  1,blah

In general the syntax feature is "offset(regD,regE)" where 
offset is a number less than 4096 and regD  and  regE are 
register numbers.

The address used is the sum of offset, regD and regE.
However, if either regD or regE are zero, then they  aren't
added.

If  R2  is  20000 hex, R3 is 000040 hex and memory  location
20050 hex contains 9, then

L 7,16(2,3)

will  load  register 7  with nine.  Note that the offset  is
entered in decimal, not hex.  The effective address is  thus
00010 hex+ 20000hex + 000040hex.

One  can use the offset(regD,regE) anywhere that a label  is
used.   Hence,  if registers two and three  had  the  values
20000 hex and 00040 hex, respectively, again, then

   L    1,F1
   ST   1,16(2,3)
   ST   1,0(2,3)
   ST   1,0(2,0)

would  store  the  constant  1  at  memory  locations  20050
hex,20040 hex and 20010 hex respectively.

Note that all you need to know to get an A in this class  is
the form of the instruction
   L   regC,0(0,regD)
   ST  regC,0(0,regD)
in  other  words,  the  case where  the  index  register  is
specified   as  zero  and  not  included  in   the   address
calculation.

Now, on to inspect our example:

We are treating A as an array going from 0 to 10.  Hence, we
define  it  as DC 11f'0' to allocate the eleven elements  in
array  from 0 to 10.  It also initializes all the values  to
zero.

Lines 10 through 16 implement A(I)=1.

LA 1,A makes register one point to the beginning of A.
L   3,I loads into register three, the value of I.  This  is
the subscript.
AR 3,3 doubles the value of the subscript
AR  3,3 doubles it again.  Now register 3 contains 4*I,  the
offset of A(I) from the beginning of A.
AR 1,3 adds this offset to the beginning of A.  Now register
one is pointing to A(i).
We  load up register 2 with the contant one, the item to  be
stored at A(i).
Finally, the "ST 2,0(0,1)" stores this value at A(I).

Lines 17 through 25 implement A(I+1) = 2.

LA 1,A makes register one point to the beginning of A.
L   3,I  and A 3,F1 gets the value I+1 into register  three.
This is the subscript.
AR 3,3 doubles the value of the subscript
AR  3,3  doubles it again.  Now register 3 contains 4*(I+1),
the offset of A(I) from the beginning of A.
AR 1,3 adds this offset to the beginning of A.  Now register
one is pointing to A(i).
We  load up register 2 with the contant two, the item to  be
stored at A(I+1).
Finally, the "ST 2,0(0,1)" stores this value at A(i+1).

Our next computation is A(I+3) = A(I)+A(I+1)

We do this in three separate steps:
a) obtain the value of A(I)
b)  obtain  the value of A(I+1) and add it to the value  for
A(I) obtained in step a.
c) store it in A(I+3)

Lines 26 through 31 obtain A(I).
LA 1,A makes register one point to the beginning of A.
L   3,I loads into register three, the value of I.  This  is
the subscript.
AR 3,3 doubles the value of the subscript
AR  3,3 doubles it again.  Now register 3 contains 4*I,  the
offset of A(I) from the beginning of A.
AR 1,3 adds this offset to the beginning of A.  Now register
one is pointing to A(i).
L   4,0(0,1)  retrieves the value of A(I) and leaves  it  in
register  four  to  await the computations  associated  with
addressing A(I+1).

Lines  33  through 39 perform the addition  of  A(I+1).   Of
course,  the first step is computing the address  of  A(I+1)
preparatory to the actual additon.

LA 1,A makes register one point to the beginning of A.
L   3,I  and A 3,F1 gets the value I+1 into register  three.
This is the subscript.
AR 3,3 doubles the value of the subscript
AR  3,3  doubles it again.  Now register 3 contains 4*(I+1),
the offset of A(I) from the beginning of A.
AR 1,3 adds this offset to the beginning of A.  Now register
one is pointing to A(i+1).
A 4,0(0,1) performs the addition of A(I+1) to A(I).

Now, all that remains is the store into A(I+3).
This is done by lines 40 to 46.
LA 1,A makes register one point to the beginning of A.
L   3,I  and A 3,F3 gets the value I+3 into register  three.
This is the subscript.
AR 3,3 doubles the value of the subscript
AR  3,3  doubles it again.  Now register 3 contains 4*(I+3),
the offset of A(I) from the beginning of A.
AR 1,3 adds this offset to the beginning of A.  Now register
one is pointing to A(I+3).
ST 4,0(0,1) puts the sum of A(I) and A(I+1) into A(I+3)

Finally, we encounter the unusual statement A(A(I+3)).
This  means to find out the value of A(I+3) and use it as  a
subscript of A.

Lines  49  through lines 55 compute A(I+3) and leave  it  in
register three.

Lines 56 to 60 use this value as a subscript and finally  in
line  60,  the  value of A(A(I+3)) is loaded  into  register
four.  Line 61 stores this value into I.
Unit 6.4 -- Do Loops and 1-D arrays

PROG

Set A(i)       i = 1 to 4

Then sum A(i), i = 1 to 4

CONCEPT

Just  show  a  brute  force  solution  to  having  an  array
subscript reference inside a do loop

SF

none

15.html