This handout was made up based on actual errors done by students. Now that you have been warned about them, I expect that you will never again make these errors. There will be big deductions if you do, so use this as a checklist, to ensure that your programs are properly written.
The purpose of theses rules is to make your programs clearer, better organized, and more efficient. They aren't just arbitrary rules that I made up to make your lives more difficult. I have tried to justify the rules, but if you're puzzled about why a rule exists, please ask.
Many of these forbidden situations will never arise if you code your program from a proper outline, such as a flowchart or C++ code.
The following taboo things are ruled out by proper modularity. See the handout on modularity.
The following lists things that your program should never do under any circumstance.
syscall
j label
label: move $a0 $v0
The processor will execute the first instruction (the syscall), then
execute second instruction (the jump), then execute the third
instruction (the move). Imagine if that jump instruction weren't there:
syscall
label: move $a0 $v0
The processor executes the syscall and then the move instruction. In
other words, you get exactly the same results. So, the jump
instruction is just a waste of time. It's also confusing, because the
reader expects to go someplace else.
j somewhere
move $a0 $a1
How is that move instruction ever going to get executed? In fact, it
can never be executed, because it can't be jumped to, and the previous
instruction will always jump away. The result is code that can never
run, which is a waste.
if( x == y )
<something>
else if ( x != y )
<something else>
...
If x isn't equal to y, so that the <something> doesn't get
executed, then it's pointless and wasteful to check if they are not
equal-they must be! Never do that in your C++ code; never,
ever.
Similarly, in MIPS assembly language, consider the following code:
beq $a0 $a1 then
bneq $a0 $a1 else
move $v0 $v1
Under what circumstances could the program not branch on both
instructions, thereby getting to the move instruction? It can't. One
or the other of those branch instructions must be true. In other
words, the above code is equivalent to the following:
beq $a0 $a1 then
j else
move $v0 $v1
Now we see that the move instruction is unreachable. The code needs
more rewriting before it makes sense.
j end
...
end: j loop
Just jump to the next piece of working code. Can you imagine looking up
``foo'' in a dictionary, and it says ``see `bar''' and when you look
up ``bar,'' it says ``see `quux.''' You'd be pretty peeved about
bouncing around the dictionary like that. Similarly, the reader of your
code will be unhappy. It's also a waste of execution time: executing
two jump instructions when one will do.
move $t0 $a0
add $a0 $a1 $zero
move $a1 $t0
This code was actually submitted by a student. Presumably, she knew
about the move instruction on the first line, forgot about it
on the second, and remembered it on the third. In other words, the
above code is evidence of either temporary amnesia or temporary
insanity. In other cases, a student uses move in one part of
the program, but not in another. The pseudo-instructions are clearer
and easier to understand, so use them
slt $t0 $a0 $a1
move $v0 $v1
beq $t0 $0 foo
Why not just do it like this:
move $v0 $v1
slt $t0 $a0 $a1
beq $t0 $0 foo
The only reason I can think of for wanting to do this is if the value
needs to be stored, calculated with, or something else before the
comparison is made. It's hard to thing of a good example, so avoid
this.