# Arrays and `lw/sw`

### Consider the following C code segment:

```        /* Initialize every other element in array A to 0 */
/* (assume numVals is number of values in A) */
int i;
for ( i = 0; i < numVals; i += 2 )
A[i] = 0;
```

### MIPS translation using array indexing:

Assume that `\$a0` holds `A` (address of beginning of array), and `\$a1` holds `numVals`.
```        move \$t0, \$zero

LOOP:   slt \$t1, \$t0, \$a1
beq \$t1, \$zero, ENDLP

sll \$t2, \$t0, 2
sw  \$zero, 0(\$t3)

j LOOP
ENDLP:  ...
```
```# \$t0 = i = 0

# \$t1 = 1 if i < numVals
# leave loop if i >= numVals

# \$t2 = 4 * i
# t3 = A + 4i, i.e., &A[i]
# store 0 out to A[i]

# i += 2
```
1000 (`A[0]`) 00000000000000000000000000000000
1004 (`A[1]`) --------------------------------
1008 (`A[2]`) 00000000000000000000000000000000
1012 (`A[3]`) --------------------------------
1016 (`A[4]`) --------------------------------
1020 (`A[5]`) --------------------------------
1024 (`A[6]`) --------------------------------
1028 (`A[7]`) --------------------------------
1032 (`A[8]`) --------------------------------
1036 (`A[9]`) --------------------------------
```    Step 1: i=0, t2=0, t3=1000, store 32 0's to A[0]
Step 2: i=2, t2=8, t3=1008, store 32 0's to A[2]
-----------
Step 3: i=4, t2=16, t3=1016, store 32 0's to A[4]
Step 4: i=6, t2=24, t3=1024, store 32 0's to A[6]
Step 5: i=8, t2=32, t3=1032, store 32 0's to A[8]
```

#### What's the deal with the `lw/sw` offset?

The instruction
`    sw \$zero, 0(\$t3) `
means: "store the contents of \$zero in memory at address \$t3 + 0". Why did we need to calculate `\$t3 = A + \$t2`? Why couldn't we just use `A` as the base address and `\$t2` as the offset?
`    sw \$zero, \$t2(\$a0)`
Syntax: the offset has to be a constant. When stepping through an array, we don't have a constant offset, so we have to calculate the exact address and then use a 0 offset.

#### Is the `lw/sw` offset ever useful?

Yes, but not when stepping through arrays.

#### Stack example

Assume that `\$sp` is 2048, `\$ra` holds 32772, `\$a0` holds 1026, and `\$a1` holds 85.
```PROC:   addi \$sp, \$sp, -12
sw  \$ra, 0(\$sp)
sw  \$a0, 4(\$sp)
sw  \$a1, 8(\$sp)
...
lw  \$a1, 8(\$sp)
lw  \$a0, 4(\$sp)
lw  \$ra, 0(\$sp)
jr \$ra
```
```# adjust \$sp to 2036 for 3 values
# save \$ra to 2036
# save \$a0 to 2040
# save \$a1 to 2044
# ... procedure contents here ...
# restore \$a1 from 2044
# restore \$a0 from 2040
# restore \$ra from 2036
# adjust \$sp back to 2048
# jump back to calling routine
```