```## LSU EE 4720 -- Spring 2022 -- Computer Architecture
#
## Array Access Examples

# Time-stamp: <28 January 2022, 14:28:56 CST, koppel@cyc.ece.lsu.edu>

################################################################################
## Array Access Examples

## Array Access
#
#   Consider the C code:
#
#      int a;
#      ...
#      x = a;
#
#   How do we convert it to assembly language?
#
#   Key Pieces of Information:
#
#     The C variable "a" holds the address of the start of the array.
#     The size of an int in this compiler is 4 bytes.
#
#   Let's assume that the compiler or assembler assigns "a" to
#   register \$t1.
#
#   Let us also assume that the compiler assigned C variable x
#   to register \$t2.
#
#   Then the C "x = a;" statement in assembly language would be:
#
lw \$t2, 0(\$t1)
#
#
#   This was easy because the array index is zero.
#
# Given the base address of an array (address of first element, say &a),
# need to compute the address of an element at index i, (say, & a[i] ).
# To do this compute:
#
#     i * sizeof( a )
#
#  In English:
#     Address of i'th element of a is the address of a + i * size of element.
#
## Element Sizes
#
#   Some languages specify exact sizes for types, ..
#   .. such as 4 bytes for an integer.
#
#   C IS NOT one of those languages.
#   Nor is C++, C++11, C++20.
#
#   An informal terminology indicates the data model (sizes of C types):
#
#     ILP32:
#     int, long, void* (Pointers) are 32 bits (four characters).
#     short, 16 bits.
#
#     LP64
#     long,  void* (Pointers) are 64 bits (eight characters).
#     int, 32 bits,
#
#     ILP64
#     int, long, void* (Pointers) are 64 bits (eight characters).
#
#   For MIPS code, assume an ILP32 data model.
#   Otherwise, assume LP64.

# :Example:
#
# Appearing below are fragments of C code along with the equivalent
# MIPS assembler. In most fragments i is the index (the number of the
# element to load). Note that i must be multiplied by the size of the
# element before adding it on to the address of the first element.
#

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
# char *c; ...      # \$s4 = c;  \$t0 = i
# x = c[i];
#

lb \$t1, 0(\$t5)      # x = c[i];   \$t1 -> c[i]

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
# char *c; ...      # \$s4 = c;  \$t0 = i
# x = c[i+1] + c[i+2];
#

## WARNING: naïve:
lb \$t6, 0(\$t5)      # \$t6 -> c[i+1]
lb \$t7, 0(\$t5)      # \$t7 -> c[i+2]

# The is the way it should be done.
lb \$t6, 1(\$t5)      # \$t6 -> c[i+1]
lb \$t7, 2(\$t5)      # \$t7 -> c[i+2]

add \$t1, \$t6, \$t7   # x = c[i+1] + c[i+2]

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
# int *a; ...       # \$s1 = a;  \$t0 = i    sizeof(int) = 4 chars.
# x = a[i];

sll \$t5, \$t0, 2     # \$t5 -> i * 4;  Each element is four characters.
lw \$t1, 0(\$t5)      # x = a[i];   \$t1 -> a[i]

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
# int *a; ...       # \$s1 = a;  \$t0 = i
# x = a[i+1] + a[i+2];
#

sll \$t5, \$t0, 2     # \$t5 -> i * 4;  Each element is four characters.
lw \$t6, 4(\$t5)      # \$t6 -> a[i+1]
lw \$t7, 8(\$t5)      # \$t7 -> a[i+2]
add \$t1, \$t6, \$t7   # x = a[i+1] + a[i+2]

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
# int x, j, *a, *b; # \$t1 = x;  \$t2 = j;  \$s1 = a;  \$s2 = b
# // Assume: a = 0x1000
# j = 3;
# b = a + j;   // b <= 0x100c   b = &a
# x = *b;      // x = a;

addi \$t2, \$0, 3     # j = 3;
sll \$t5, \$t2, 2     # \$t5 -> j * 4
add \$s5, \$s1, \$t5   # b = a + j;
lw \$t1, 0(\$s5)      # x = *b = a[j]

# Optimized
lw \$t1, 12(\$s1)      # x = a

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
# short *s; ...     # \$s2 = s;  \$t0 = i;  sizeof(short) = 2 chars
# x = s[i];
#

sll \$t5, \$t0, 1     # \$t5 -> i * 2;  Each element is two characters.
lh \$t1, 0(\$t5)      # x = s[i];   \$t1 -> s[i]

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
# short *s; ...     # \$s2 = s;  \$t0 = i
# x = s[ s[i] ];
#

sll \$t5, \$t0, 1     # \$t5 -> i * 2;  Each element is two characters.
lh \$t8, 0(\$t5)

sll \$t5, \$t8, 1     # \$t5 -> i * 2;  Each element is two characters.
lh \$t1, 0(\$t5)

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#
#                     \$s3 = us;  \$t0 = i
# unsigned short *us;
# x = us[i];
#

sll \$t5, \$t0, 1     # \$t5 -> i * 2;  Each element is two characters.
lhu \$t1, 0(\$t5)      # x = us[i];   \$t1 -> us[i]

## C CODE                     #  ASM REGISTER = C VARIABLE NAME
#              0      4       5          8
# struct str { int i; char c; char p; int j };
# str a;
# ..
# x = a.i + a.c + a.j + a.p; // \$t1 -> x;    \$a1 -> &a (address of a)

# \$a1 is address of a;
lw \$t1, 0(\$a1)  # \$t1-> a.i;
lb \$t2, 4(\$a1)  # \$t2-> a.c;
lw \$t3, 8(\$a1)  # \$t3-> a.j
lb \$t4, 6(\$a1)  # \$t4-> a.p