Given the following code (main.s
):
给定以下代码(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
:
SPIM得到REG 9=0x00000000(0)。但是,在仅添加一个管路时:
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.
SPIM突然产生正确值REG 9=0x00000085(133)。如果在第二次运行之前运行重新初始化,也会发生这种情况,但奇怪的stdin管道不允许这样做。
Why does this happen?
这一切为什么要发生?
更多回答
I'm using QtSpim, which, confusingly, has two bare machine options.
我使用的是QtSpim,令人困惑的是,它有两个裸机选项。
The first is a single check box for Bare Machine
第一个是裸机的单个复选框
- This option changes the location for
.data
(perhaps among other things) from 0x10010000 (default) to 0x10000000.
The second is a push button for Bare Machine
that reconfigures all the check box options.
第二个按钮是Bare Machine的按钮,用于重新配置所有复选框选项。
- It will select the
Bare Machine
check box, and also among the check boxes selected by the push button, is
Enable Delayed Loads
.
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.
我相信SPIM上的-Bare和QtSpim上的按钮是一样的,QtSpim上的按钮既包括“裸机”,也包括数据位置更改,加上延迟加载和延迟分支。
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.
延迟加载是原始MIPS处理器的一个方面,因此任何加载指令的结果都不会出现在额外周期/指令的目标寄存器中。
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.
不知何故,如果您在没有重新初始化的情况下再次运行,这些结果就会出现--虽然我不能使用QtSpim重现(没有可以使用两次的“run”命令),但似乎您正在进行的第二次运行提供了完成(第一次运行)加载所需的额外一个周期。
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.
要修复以便在第一次运行时看到$T1中的133/0x85,只需再添加一条指令,例如Addu$0,$0,$0-这条额外的指令跟随在最终加载之后,并覆盖加载延迟加载选项所需的额外周期。
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.
NOP伪指令通常是一种可接受的填充延迟槽的方法,但使用-Bare选项(至少来自QtSpim)时,将禁用接受伪指令复选框,因此NOP伪指令不可用,必须使用真实指令。
更多回答
Thank you for the response! Unfortunately, 1 addu
still yielded the same behavior as in the question. I've also tested this on QtSpim with these settings: chortle.ccsu.edu/AssemblyTutorial/Chapter-09/ass09_06.html, and the behavior is the same: $t1 = 0
unless QtSpim is reinitialized once (Simulator > Reinitialize Simulator) and ran again (with the same play button), and then $t1 = 133
as expected. Oddly enough, this is fixed with 2 addu
s instead of 1.
感谢您的回复!不幸的是,1 Addu仍然产生了与问题中相同的行为。我也测试了QtSpim上的这些设置:chortle.ccsu.edu/AssemblyTutorial/Chapter-09/ass09_06.html,和行为是相同的:$t1=0,除非QtSpim重新初始化一次(模拟器>重新初始化模拟器)并再次运行(使用相同的播放按钮),然后$T1=133如预期。奇怪的是,这是用2个ADDUS而不是1来修复的。
As a side note, 2 addu
s worked with spim -bare -delayed_loads -nomapped_io -noexception
, but not spim -delayed_loads -nomapped_io -noexception
, even though the second arguments mirror the usage message for -bare
minus the pseudo-ops!
另外请注意,2 ADDU可以使用spim-are-delayed_Loads-nomap_io-noception,但不能使用spim-delayed_Loads-nomap_io-noception,即使第二个参数反映了-are的用法消息,减去了伪操作!
Ok, interesting, and a bit unexpected. Well, looks like has something to do with delayed loads, can't guess further why your system and mine differ.
好吧,有趣,有点出乎意料。好吧,看起来像有东西做延迟加载,不能猜测进一步为什么你的系统和我的不同。
我是一名优秀的程序员,十分优秀!