SPIM模拟器中lbu指令首次运行读取失败、二次运行才正常的原因咨询
这问题挺有意思的,我之前也碰到过类似的SPIM怪异行为,咱们来拆解一下背后的原因:
SPIM在-bare模式下的内存初始化时序问题
当你用spim -bare -noexception启动模拟器,再通过管道输入命令时,load "main.s"命令会把汇编代码的.text和.data段解析出来,但在第一次执行run命令前,SPIM可能还没把.data段的实际数据写入到模拟内存的对应地址(也就是0x10000000开始的区域)。
第一次run的时候,程序执行lbu $t1, 2($t0),此时0x10000002地址的内存还是模拟器默认的初始值0,所以$t1(也就是$9)读到的是0。而第一次run结束后,SPIM才完成了数据段内容的内存写入操作,第二次run时,内存里已经有你定义的0x85(133)了,所以能读到正确值。管道输入导致的命令执行时序偏差
你用cat << EOF | spim ...这种管道方式批量输入命令,SPIM是按顺序读取并执行,但管道的流式输入可能会让SPIM在还没完全处理完load命令的所有初始化步骤(比如数据段内存的持久化写入)时,就开始执行run命令了。如果是手动逐个输入命令,大概率不会有这个问题——因为你输入load后会有停顿,SPIM有足够时间完成所有初始化工作。关于
reinitialize命令的补充
你提到如果在第二次run前执行reinitialize也能解决问题,但管道输入场景下不好操作——这是因为reinitialize命令会强制SPIM重新初始化所有模拟内存,包括把.data段的内容重新写入到对应地址,所以之后的run就能读到正确值了。
简单总结:本质上是SPIM在-bare模式+管道批量输入命令的场景下,数据段内存初始化的时序不匹配导致的,第一次run时数据还没到位,第二次run时数据已经加载完成了。
备注:内容来源于stack exchange,提问作者diamondburned

