One of my homework questions was to find the 3rd element stored in an array in MIPS, here is my code

la $t0, array0 # Loads the address of variable array0 into $t0
lw $t1, 12($t0) # Loads the value of the 3rd element of variable array0 using the address stored of array0 in $t0 into $t1
li $v0, 1 # Set $v0 to 1, this tells syscall to # print the integer specified by $t1
syscall # Now print the integer

Now the next instruction is to store the value in the register $s2. My confusion at this moment is whether to use SW(store word) $s2, $t1 or LW(load word) $s2, $t1. If anyone could please give a sound explanation of the what the correct answer is and how to figure out when to use SW or LW, would be very much appreciated.

  • \$\begingroup\$ Are you loading it from memory or storing it to memory? \$\endgroup\$ Oct 5, 2014 at 16:20
  • \$\begingroup\$ @IgnacioVazquez-Abrams See thats where i am confused. Our instructions were to find the 3rd element in an array, print the value, and then store it in the $s2 register \$\endgroup\$ Oct 5, 2014 at 16:29

3 Answers 3

  • LW loads a word from memory into a register.
  • SW saves a word from a register into RAM.

To copy from one register to another you would typically perform an operation which resulted in the data of one register being copied intact into the other register, such as:

or $s2, $zero, $t1

That has the effect of ORing the value in $t1 with the value in $zero (which is always zero), the result of which is $t1 unmodified, which is then placed in $s2.

MIPS can be confusing as there is no instruction specifically for copying from one register to another, but then that's the essence of RISC - why have a MOVE instruction when you can perform the same operation with an OR? It just wastes instructions.

Most assemblers have a collection of macros to make your life easier. You may well find that yours has support for a virtual MOVE instruction, as well as others. Some expand to just one instruction, but some expand to more than one, such as "li", which usually expands to something along the lines of:

lui $t1, %HI(val)
ori $t1, $t1, %LO(val)

I.e., load the upper 16 bits into $t1, then OR the lower 16 bits over the top of it.

  • \$\begingroup\$ Interestingly, MIPS (at least Releases 5 and 6, as far as I can tell) do not define a canonical MOV instruction. This may be a bit painful if an implementation decides to do move elimination. Also interesting (to me at least) is MIPS calling such "assembly idioms", but applying the same term to instructions that have semantic differences from the normal interpretation of the instruction encoding such as Superscalar NOP and Execution Hazard Barrier. \$\endgroup\$ Oct 5, 2014 at 20:38

Wikipedia gives a reasonable overview of MIPS Instruction Set

AFAIK, MIPS assemblers support the move instruction, so move $s2, $t1 would 'just work'.
It uses a different instruction to achieve the effect (maybe add $s2, $t1, $zero, or or ... ) however move is easier to read and understand.

IMHO the notation used at wikipedia is quite helpful:

lw $t,C($s)     # $t = Memory[$s + C]
sw $t,C($s)     # Memory[$s + C] = $t

If you are using 'SPIM Simulator', then this MIPS Quick Tutorial says that print_int, which is called with $v0 = 1, which is your example code, has the parameter, the integer to be printed, in $a0.

So if the intention is to print the third integer in the array, it would be better to load that 3rd value from the array into $a0, and not $t1, i.e. lw $a0, 12($t0)


I guess the confusion comes from the fact that in MIPS assembly syntax normally the destination operand is the left (most) one.

This is not the case in the sw instruction:
In the sw istruction the left operand register is stored to the memory address based on the right operand register.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.