4
votes
for (i = 0; i < 64; i++) {
A[i] = B[i] + C[i];
}

The MIPS instructions for the above C code is:

add $t4, $zero, $zero   # I1 i is initialized to 0, $t4 = 0
Loop: 
add $t5, $t4, $t1       # I2 temp reg $t5 = address of b[i]
lw $t6, 0($t5)          # I3 temp reg $t6 = b[i]
add $t5, $t4, $t2       # I4 temp reg $t5 = address of c[i]
lw $t7, 0($t5)          # I5 temp reg $t7 = c[i]
add $t6, $t6, $t7       # I6 temp reg $t6 = b[i] + c[i]
add $t5, $t4, $t0       # I7 temp reg $t5 = address of a[i]
sw $t6, 0($t5)          # I8 a[i] = b[i] + c[i]
addi $t4, $t4, 4         # I9 i = i + 1
slti $t5, $t4, 256       # I10 $t5 = 1 if $t4 < 256, i.e. i < 64
bne $t5, $zero, Loop    # I11 go to Loop if $t4 < 256

For I8, could the sw instruction not be replaced with an addi instruction? i.e addi $t5, $t6, 0

Wouldn't it achieve the same task of copying the address of $t6 into $t5? I would like to know the difference and when to use either of them. Same could be said about the lw instruction.

Also, maybe a related question, how does MIPS handle pointers?

edit: changed addi $t6, $t5, 0.

4

4 Answers

4
votes

The sw instruction in MIPS stores the first argument (value in $t6) to the address in the second argument (value in $t5) offset by the constant value (0).

You're not actually trying to store the $t5 address into a register, but rather storing the value in $t6 into the memory location represented by the value of $t5.

If you like, you could consider the value in $t5 to be analogous to a C pointer. In other words, MIPS does not handle pointers vs values differently-- all that matters is where you use the values. If you use a register's value as the second argument to lw or sw, then you are effectively using that register as a pointer. If you use a register's value as the first argument to lw or sw, or in most other places, you are operating directly on the value. (Of course, just like in C pointer arithmetic, you might manipulate an address so you can store a piece of data somewhere else in memory.)

3
votes

For I8, could the sw instruction not be replaced with an add instruction? Wouldn't it achieve the same task of copying the address of $t5 into $t0? I would like to know the difference and when to use either of them.

I think you are confused with what a store word actually does. In I8, the value of the register in $t6 is being stored into $t5 at position zero. An add will overwrite whatever data is stored in the destination register with the sum of the two other registers' values.

Also, maybe a related question, how does MIPS handle pointers?

The "pointers" are just addresses in memory stored in the registers (as opposed to values).

3
votes

lw and sw read/write to memory. addi and other arithmetic operations operate on registers.

Registers are like little buckets the CPU uses to store data. They can be addressed in 5 bits or so if I remember my MIPS architecture correctly.

Memory is like a vast ocean of data that requires well over 16 bits to address. So you actually have to store the address in a register.

Pointers are simply memory addresses (32 bit on a 32 bit architecture).

3
votes

For I8, could the sw instruction not be replaced with an addi instruction? i.e addi $t6, $t5, 0

No. The sw instruction stores the result to memory. The add just manipulates registers. And lw gets a word from memory. It's the only MIPS instruction that does so. (Other processors might and do have versions of add that access memory, but not MIPS.)

It's necessary to adjust your thinking when working in assembly language. Registers and memory are separate. In higher level languages, registers are (nearly) completely hidden. In assembly, registers are a separate resource that the programmer must manage. And they're a scarce resource. A HLL compiler would do this for you, but by programming in assembly, you have taken the job for yourself.

how does MIPS handle pointers?

In MIPS, pointers are just integers (in registers or memory) that happen to be memory addresses. The only way they're distinguished from data values is by your brain. The "pointer" is something invented by higher level language designers to relieve you the programmer of this burden. If you look closely, you'll see that $t5 actually holds a pointer. It's a memory address used by lw and sw as the address to load from or store to.