## LSU EE 4720 -- Spring 2018 -- Computer Architecture
#
## Array Access Examples

# Time-stamp: <2 February 2018, 14:54:43 CST, koppel@cyc.ece.lsu.edu>


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

 ## Array Access
#
#   Consider the C code:
#
#      int a[10];
#      ...
#      x = a[0];
#
#   How do we convert it to assembly language?
#
#   Key Piece of Information:
#
#     The C variable "a" holds the address of the start of the array.
#
#   Lets 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[0];" statement in assembly language is:
#
        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[0]),
# need to compute the address of an element at index i, (say, &a[i]).
# To do this compute:
#
#     i * sizeof( a[0] )
#
#  In English:
#     Address of i'th element of a is the address of a + i * size of element.



# :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];
        #

        add $t5, $s4, $t0   # $t5 -> &c[i]  (Address of 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];
        #


        add $t5, $s4, $t0   # $t5 -> &c[i]  (Address of c[i].)
        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
        # x = a[i];

        sll $t5, $t0, 2     # $t5 -> i * 4;  Each element is four characters.
        add $t5, $s1, $t5   # $t5 -> &a[i]  (Address of a[i].)
        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.
        add $t5, $s1, $t5   # $t5 -> &a[i]  (Address of a[i].)
        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
        # x = *b;      // x = a[3];

        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]


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

        sll $t5, $t0, 1     # $t5 -> i * 2;  Each element is two characters.
        add $t5, $s2, $t5   # $t5 -> &s[i]  (Address of s[i].)
        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.
        add $t5, $s2, $t5   # $t5 -> &s[i]  (Address of s[i].)
        lh $t8, 0($t5)

        sll $t5, $t8, 1     # $t5 -> i * 2;  Each element is two characters.
        add $t5, $s2, $t5   # $t5 -> &s[i]  (Address of s[i].)
        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.
        add $t5, $s3, $t5   # $t5 -> &us[i]  (Address of us[i].)
        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[3]; int j };
        # str a;
        # ..
        # x = a.i + a.c + a.j + a.p[1]; // $t1 -> x;    $a1 -> &a (address of a)

        lw $t1, 0($a1)  # $t1-> a.i;
        lb $t2, 4($a1)  # $t2-> a.c;
        lw $t3, 8($a1)  # $t3-> a.j
        add $t1, $t1, $t2
        add $t1, $t1, $t3
        add $t1, $t1, $t4


####