One thing you need to be aware of is that the MIPS architecture (like many RISC architectures) has a number of instructions that do not take effect right away. Instructions that fetch values from memory, for example, take so long to execute that another instruction (that doesn't access memory) can be executed before the memory access completes. Such instructions are called delayed loads; the loaded value doesn't become available right away. The MIPS architecture executes one instruction during such load delay slots.
In many cases, the compiler can rearrange the order of instructions in order to fill the delay slot with useful instruction. For example, a value could be loaded a few instructions earlier than it is actually needed, as long as the target register was not being used. When tracing programs in Nachos, you should be aware that instructions used in calling subroutines have a one-instruction delay. That is, the PC can be changed quickly, but the processor must go to memory to fetch the instruction at the new address before it can actually execute it. Thus, the code for calling the procedure Exit with an argument of 0 would be done as follows:
jal Exit # Jump to procedure ``Exit''
addu r4,0,0 # r4 <= r0 + 0 (r0 always has a value of 0)
That is, the instruction that zeroes out register r4 appears after the ``jal'' instruction, rather than before as expected.
Table describes some common instructions you may encounter.