MIPS errors with %hi and %lo

Viewed 79
lui     $v0,%hi(length)
lw      $v1,%lo(length)($v0)
li      $v0,3                        # 0x3
bne     $v0,$zero,1f
div     $zero,$v1,$v0
break   7
mfhi    $v0
mflo    $v0
sw      $v0,28($fp)
lw      $a1,28($fp)
lui     $v0,%hi(game_over)
addiu   $a0,$v0,%lo(game_over)
jal     printf
nop

When I try running this for my MIPS code, it comes up with this error:

Your program produced these errors: spim: (parser) Unknown character on line 180 of file measurement.s lui $v0,%hi(length)

spim: (parser) syntax error on line 181 of file measurement.s Instruction references undefined symbol at 0x00400038 [0x00400038] 0x0c000000 jal 0x00000000 [init_measure] ; 159: jal init_measure

Do I need to substitute %hi and $lo for something else in the code?

EDIT For the following code:

sw      $v0,16($fp)
lui     $a0,%hi(grid)
lw      $v1,12($fp)
nop
move    $v0,$v1
sll     $v0,$v0,4
subu    $v0,$v0,$v1
addiu   $v1,$a0,%lo(grid)
addu    $v1,$v0,$v1
lw      $v0,16($fp)

And

lui     $v0,%hi(column)
lb      $v0,%lo(column)($v0)
nop

sw      $v0,12($fp)
lui     $v0,%hi(column)
addiu   $v1,$v0,%lo(column)
lw      $v0,8($fp)
nop

addiu   $v1,$v0,-1
lui     $v0,%hi(growth)
sw      $v1,%lo(growth)($v0)
b       true
nop

Will I be substituting %hi and % lo it in a similar manner or differently?

1 Answers

Those seem to be operators not supported by spim. %LO(label) should give you the lowest half of the address of label, and %HI(label) the upper half.

You can substitute these two instructions:

lui     $v0,%hi(length)
lw      $v1,%lo(length)($v0)

with this:

la     $v0,length
lw     $v1,0($v0)

So we use la pseudoinstruction to load the whole address of the label onto a register (in the example $v0) then you directly load its memory contents using 0 as the lw offset. Note that la pseudoinstruction would use 2 instructions for an arbitrary label address (and leave $at with the upper half address). Also note that in your code $v0 would still hold the upper half of the label address whereas in the second snippet it will contain the whole address.

Similarily, instead of

lui     $v0,%hi(game_over)
addiu   $a0,$v0,%lo(game_over)

you can just issue:

la $a0, game_over

In this case, your code would end with $a0 having the address of game_over label (as in the second snippet), and $v0 holding the lower half of that address. la pseudoinstruction will leave the upper half of the label on $at

Related