1000 slt $t0, $s1, $s2 # set $t0 to 1 if $s1 < $s2 1004 beq $t0, $zero, ENDIF # goto ENDIF if $t0 != 1, aka $s1 >= $s2 . . . 1032 ENDIF:
if ( b <= c )
?
Note that( b <= c )
is equivalent to( ! (b > c) )
, which is equivalent to( ! (c < b) )
. So, set up theslt
instruction based onc < b
and then rethink thebeq
orbne
.
Why did they only implement set-on-less-than and not set-on-greater-than, for example?
beq
/bne
instruction:
Example:
1004 beq $t0, $zero, ENDIF # goto ENDIF if $t0 == 0 1008 . . . 1028 ENDIF:Machine code format:
opcode rs rt offset (16 bits) ?????? ????? ????? ???????????????? Opcodes: beq=4, bne=5 beq $t0, $zero, ENDIF 4 8 0 ? 000100 01000 00000 ????????????????
Calculating the offset:
The
beq
command is at address 1004, but by the time the command is being executed the PC has already been incremented to 1008. So, we calculate the offset from the PC to the desired label (which is at address 1028) as (1028 - 1008) = 20. But all addresses (and therefore all offsets) are divisible by 4, meaning they all end in00
in binary, so there's no need to waste 2 bits of the machine instruction on those 2 bits. So we drop those 2 bits (which we can do by dividing by 4), to get an adjusted or truncated offset of 20/4 = 5. And that's what gets stored in the machine code.beq $t0, $zero, ENDIF 4 8 0 5 000100 01000 00000 0000000000000101
offset = (addrFromLabelTable - PC) / 4 PC = PC + (offset * 4)