assemblymipsqtspimspim

MIPS lbu doesn't work unless program is run twice


Given the following code (main.s):

        .text  
        .globl main

main:
        lui $t0, 0x1000
        lbu $t1, 2($t0)

        .data 
        .byte 0
        .byte 0
        .byte 133

When executed with

cat << EOF | spim -bare -noexception
load "main.s"
run 0x400000
print \$9
EOF

SPIM yields Reg 9 = 0x00000000 (0). However, when adding just one more run:

cat << EOF | spim -bare -noexception
load "main.s"
run 0x400000
run 0x400000
print \$9
EOF

SPIM suddenly yields the correct value of Reg 9 = 0x00000085 (133). This also happens if reinitialize is ran before the second run, but the weird stdin piping doesn't allow for that.

Why does this happen?


Solution

  • I'm using QtSpim, which, confusingly, has two bare machine options. 

    I believe that -bare on Spim is the same as the push button on QtSpim, which includes both the "Bare Machine" .data location change, plus Delayed Loads and Delayed Branches.

    Delayed loads is a aspect of the original MIPS processor and with it the results of any load instruction do not appear in the target register for an additional cycle/instruction.

    So, since your program ends with a load instruction, and also is using the Delayed Load option, effectively, such program is too short to see the result of that final load operation.

    Somehow those results do appear if you run again without reinitialization — while I cannot reproduce using QtSpim (there's no "run" command that can be used twice), it would appear that this second run you're doing provides that extra one cycle needed to finish the (first run's) load.

    To fix so that you see the 133/0x85 in $t1 on the first run, simply add one more instruction, e.g. addu $0, $0, $0 — this additional instruction to follow that final load and cover the extra cycle needed by the load with delayed loads option.

    A nop pseudo instruction would normally be an acceptable way to fill a delay slot, but with the -bare option (at least from QtSpim), the check box Accept Pseudo Instructions is disabled, so the nop pseudo instruction is not available, have to do it using a real instruction.