c++ - 在 C++ 的功能 ISA 模拟器上实现陷阱(异常/中断)

标签 c++ mips qemu emulation riscv

我尝试实现功能性 ISA 模拟器:目标是 RISC-V 和 MIPS。 它是一步一步的指令解释器。

抽象步骤:

while(num_steps)
{
    try
    {
        take_interrupt();// take pending interrupts
        fetch(); // fetch instruction from memory
        decode(); // find handler to instruction
        execute(); // perform instruction
    } 
    catch (Trap& e)
    {
        take_trap(e); //configure appropriate system registers and jump to trap vector.
    }
}

如您所见,C++ 异常用于传输控制流。 也许可以有更帅气的设计?

问题:在功能性 ISA 模拟器上实现陷阱的最佳方法/实践是什么。我也对翻译模拟器(如 QEMU)的异常/陷阱实现感兴趣。

注意: trap 这个词是指 ISA 定义的陷阱,而不是应用程序错误:未对齐的内存访问、非法指令、系统寄存器访问错误、特权级别更改等.

最佳答案

QEMU 使用 C setjmp()/longjmp() 机制来处理大多数异常:当我们检测到页面错误之类的东西时,我们设置一些标志来指示异常类型,然后 longjmp() 到顶部 -级别“执行代码”循环。该循环然后查看标志并在继续执行客户代码之前将 CPU 状态设置为“进入异常处理程序”。

所以我们使用 C 等价物来抛出异常;正如 NonNumeric 所说,不需要像这样实现 guest 异常(名称的巧合只是巧合)。但是由于触发页面错误的内存访问是不常见的情况,longjmp 或抛出 C++ 异常比在所有内存访问代码路径中包含“处理失败返回”更有效。 guest 内存访问是一个特殊的热点,QEMU 使用一些自定义内联汇编实现其内存访问快速路径,因此我们关心在页面错误时退出到顶级循环而不执行 longjmp 所需的额外指令.使用简单的“获取/解码/执行”循环而不对 guest 代码执行 JIT 的模拟器不太关心性能,因此您的选择可能取决于代码风格和可维护性的偏好。

关于c++ - 在 C++ 的功能 ISA 模拟器上实现陷阱(异常/中断),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37388990/

相关文章:

linux - 如何使用QEMU学习ARM Linux内核开发?

c++ - 无法为 Eclipse CDT 安装 LLVM 工具链

c++ - 在 C++ 中用一个 if 满足两个条件

assembly - 管道危险

assembly - 帧指针 MIPS 的使用

gdb - 如何用GDB调试交叉编译的QEMU程序?

c++ - 将包含不可复制/可移动对象的结构添加到 std::map

c++ - 如何删除此代码输出的结尾空格

assembly - 如何在 MIPS Assembly 中执行递归操作?

linux - QEMU 错误且权限被拒绝