Gotchas: Difference between revisions

no edit summary
No edit summary
Line 159:
EXT.L D1 ;D1 = $FFFF8000</syntaxhighlight>
 
=={{header|MIPS AssemblyC}}==
===Delay Slotsif(a=b)===
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="mipsC">moveif(a=b){} $t0//assigns to "a" the value of "b". Then,$zero if "a" is nonzero, the code in the ;loadcurly 0braces intois $t0run.
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:
1,489

edits