Gotchas: Difference between revisions
no edit summary
Puppydrum64 (talk | contribs) |
Puppydrum64 (talk | contribs) No edit summary |
||
Line 159:
EXT.L D1 ;D1 = $FFFF8000</syntaxhighlight>
=={{header|
===
This is an easy mistake to make if you're in a hurry. The ''assignment operator'' <code>=</code> is different from the ''equality comparison operator'' <code>==</code>. Therefore you have the following similar looking but vastly different statements, both of which are valid.
Due to the way MIPS's instruction pipeline works, an instruction placed after a branch instruction is executed during the branch, ''even if the branch is taken.''▼
<syntaxhighlight lang="
beqz $t0,myLabel ;branch if $t0 equals 0▼
addiu $t0,1 ;add 1 to $t0. This happens during the branch, even though the program counter never reaches this instruction.</syntaxhighlight>▼
if(a==b){} //runs the code in the curly braces if and only if the value of "a" equals the value of "b".</syntaxhighlight>
Now, you may think that the 1 gets added first and therefore the branch doesn't take place since the conditions are no longer true. However, this is '''not the case.''' The condition is already "locked in" by the time <code>addiu $t0,1</code> finishes. If you compared again immediately upon arriving at <code>myLabel</code>, the condition would be false.▼
The easiest way to fix this is to put a <code>NOP</code> (which does nothing) after every branch.▼
On earlier versions of MIPS, this also happened when loading from memory. The register you loaded into wouldn't have the new value during the instruction after the load. This "load delay slot" doesn't exist on MIPS III (which the Nintendo 64 uses) but it does exist on the PlayStation 1.▼
<syntaxhighlight lang="mips">la $a0,0xDEADBEEF▼
lw $t0,($a0) ;load the 32-bit value at memory address 0xDEADBEEF▼
addiu $t0,5 ;5 is actually added BEFORE the register has gotten its new value from the memory load above. It will be clobbered.</syntaxhighlight>▼
Like with branches, putting a <code>NOP</code> after a load will solve this problem.▼
=={{header|J}}==
Line 295 ⟶ 283:
</pre>
=={{header|MIPS Assembly}}==
===Delay Slots===
▲Due to the way MIPS's instruction pipeline works, an instruction placed after a branch instruction is executed during the branch, ''even if the branch is taken.''
<syntaxhighlight lang="mips">move $t0,$zero ;load 0 into $t0
▲beqz $t0,myLabel ;branch if $t0 equals 0
▲addiu $t0,1 ;add 1 to $t0. This happens during the branch, even though the program counter never reaches this instruction.</syntaxhighlight>
▲Now, you may think that the 1 gets added first and therefore the branch doesn't take place since the conditions are no longer true. However, this is '''not the case.''' The condition is already "locked in" by the time <code>addiu $t0,1</code> finishes. If you compared again immediately upon arriving at <code>myLabel</code>, the condition would be false.
▲The easiest way to fix this is to put a <code>NOP</code> (which does nothing) after every branch.
▲On earlier versions of MIPS, this also happened when loading from memory. The register you loaded into wouldn't have the new value during the instruction after the load. This "load delay slot" doesn't exist on MIPS III (which the Nintendo 64 uses) but it does exist on the PlayStation 1.
▲<syntaxhighlight lang="mips">la $a0,0xDEADBEEF
▲lw $t0,($a0) ;load the 32-bit value at memory address 0xDEADBEEF
▲addiu $t0,5 ;5 is actually added BEFORE the register has gotten its new value from the memory load above. It will be clobbered.</syntaxhighlight>
▲Like with branches, putting a <code>NOP</code> after a load will solve this problem.
=={{header|Perl}}==
Perl has lists (which are data, and ephemeral) and arrays (which are data structures, and persistent), distinct entities but tending to be thought of as inter-changable. Combine this with the idea of <i>context</i>, which can be 'scalar' or 'list', and the results might not be as expected. Consider the handling of results from a subroutine, in a scalar context:
|