MIPS:将两个连续的"load word"指令放入同一个寄存器是否合法?



背景:我们在函数foo(int *p)中看到非常间歇性崩溃。崩溃是在取消p时发生的,在这些情况下,其值为0xffffffff。对核心转储的分析表明,从以下组装片段中调用foo()

bne ... somewhere else
lw $a0,44(sp)
lw $a0,40(sp)
jal foo()
lui s1, 0x1000

检查核心转储中的内存表明44(sp)0xffffffff,而40(sp)是我们打算取消的正确值。但是,崩溃时a0的值是foo()内部的0xffffffff。(重要的是要注意,在这种情况下,foo()只是访问成员;因此,这实际上是foo()中的第一个指令,该指令已经尝试通过a0访问,并且崩溃了。此外,ra指向上述snippet和上述snippet和s1当前包含0x10000000,因此我们非常有信心foo()确实是从上述片段中调用的。)

目前,我们唯一的理论是,a0中的两个连续的lw s是一种危害 - 要么是记录在案的危险,在这种情况下,这看起来像是编译器错误。或一个无证的。

so :上述组件合法吗?如果是这样,关于这里可能发生的事情的其他想法?

谢谢!

update :嗯,事实证明这是一次野鹅追逐:对同事对Coredump的重复分析,在我错过的代码中,有一条我错过的路径将a0设置为44(sp)之后,直接直接发送到jal foo()指令。换句话说,代码中有一条路径与我们看到的结果一致,它不涉及危害,"跳过说明"或其他任何内容...我想我检查了一下,但是我想我要么没有't或错过了... :(

无论如何,我已经接受了Markgz的答案,因为它回答了我关于这些说明合法性的最初问题(显然是)。

对MIPS32R2 ISA的MIPS文档进行快速搜索,在LW指令后没有显示对LW的任何限制。

可能是您CPU中MIPS实现的错误。要看的东西包括:

  • 哪个地址是44(sp),40(sp) - 它们在页面边界还是256米边界或其他有趣的地址?
  • 任何一个负载触发了页面故障?
  • 修补二进制文件是否插入NOPSSNOP或负载之间的SYNC指令使问题消失了?

最新更新