Gotchas: Difference between revisions

Content added Content deleted
Line 41: Line 41:
<lang 68000devpac>LEA $A04000,A0 ;effectively MOVEA.L #$A04000,A0
<lang 68000devpac>LEA $A04000,A0 ;effectively MOVEA.L #$A04000,A0
LEA (4,A0),A0 ;effectively ADDA.L #4,A0</lang>
LEA (4,A0),A0 ;effectively ADDA.L #4,A0</lang>

=={{header|MIPS Assembly}}==
===Delay Slots===
Due to the way MIPS's instruction pipeline works, an instruction after a branch is executed during the branch, ''even if the branch is taken.''

<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.</lang>

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.

<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.</lang>

Like with branches, putting a <code>NOP</code> after a load will solve this problem.


=={{header|J}}==
=={{header|J}}==