【问题标题】:MIPS exception handling (Specifically branch delay slots)MIPS 异常处理(特别是分支延迟槽)
【发布时间】:2011-06-03 00:02:02
【问题描述】:

假设在条件分支的分支延迟槽中遇到异常

例如

    BEQ a0, zero, _true
    BREAK (0000)
    sw a0, 0000(t0)
_true:
    sw a1, 0000(t0)

我的异常处理程序将从 BREAK 指令中提取异常 type 9 并设置 CAUSEBD 位/em> 在分支延迟中注册为 1,EPC 将是分支的地址。

文档说这将需要未描述的复杂处理。即获取分支/跳转的目标,进行任何所需的比较,然后将 PC 设置为真或假地址。

我绕过复杂处理的解决方案(有点破解)如下:

  1. 将指令存储在分支延迟槽中
  2. NOP 分支延迟槽中的指令
  3. 从恢复所有寄存器的异常处理程序中返回
  4. 重新执行 *BEQ a0, zero, _true* 并且分支延迟将是 nop 所以它没有效果
  5. 在分支的目标处放置一个 sw 断点并设置一个标志
  6. 一旦遇到 sw 断点,就恢复分支延迟槽并移除 sw 断点的痕迹。

解析分支和跳转很好(这就是为什么我可以得到目标)但是在条件分支中,一旦我解析了,我就必须进行比较以确定是否跳转到 go to false 的 true 部分(下一行)我觉得这比我想要的要多。 不是吗?

我的 hacky 方法的问题是:

CPU 是否已经存储了它已经到达条件分支并确定在执行了分支延迟槽之后它是否要进行分支,因此一旦我指向 程序计数器 回到分支,它被执行而不是正确执行,它认为它必须跳转到在异常发生之前预先确定的分支的真或假部分? (尝试“双跳”)

【问题讨论】:

    标签: exception-handling mips


    【解决方案1】:

    你有 MIPS 程序员文档吗?如果您想要 100% 准确的答案,请阅读它们 - 如果不是,我可以告诉您我记得的重要部分。

    简而言之-是的,您需要从内存中加载指令,对其进行解析并解释结果以找出必须继续的地方。如您所说的“修补”代码也可以,但是您需要确保指令缓存无效,否则您将从缓存中运行并以无限循环结束。

    PC 的更新是在延迟槽执行之后进行的,在此之前它将指向分支。异常期间没有特殊处理,除非您有一个寄存器说明您是否处于延迟槽中。 您需要模拟所有可以有条件地在处理程序(加载/存储)中引发异常的指令以及分支指令。如果它是 DS 中的另一种指令,您可以在分支处重新启动(在这种情况下例外是外部中断)。

    如果您关心的是性能,那么就不要将异常引发指令放在延迟槽中。

    编辑:不,MIPS 不存储有关中断指令的任何内容,但您建议的方法可能会因为必须使 ICache 无效两次而变慢

    【讨论】:

    • 谢谢!是否有任何关于更高级异常处理的好文档,我只能在简单的“向 epc 中添加 4”文档中找到。在这种情况下,我并不太在意速度,因为它是用于使用软件断点进行指令步进的。
    猜你喜欢
    • 1970-01-01
    • 2013-11-18
    • 2018-07-16
    • 1970-01-01
    • 2011-10-17
    • 2012-10-21
    • 2015-03-28
    • 2013-10-09
    • 1970-01-01
    相关资源
    最近更新 更多