编写指令集模拟器的主要步骤是什么?

Ahm*_*med 4 assembly simulator

我将从事一个需要为特定指令集编写模拟器(可能不适用于真正的处理器)的项目。最好这个模拟器类似于 MIPS ISA 的 SPIM 模拟器。它将显示所有寄存器、内存位置等的内容,并让我逐步执行指令。是否有编写模拟器的标准步骤集?从哪儿开始 ?

我了解 Java 和 C++,并且完成了两门计算机体系结构课程并在 3 人团队中工作。

old*_*mer 5

我想说你需要先使用反汇编程序。模拟器是反汇编程序的下一步。例如,x86(或其他可变字长指令集)反汇编器将需要跟踪代码的执行。首先,它必须根据操作码知道该指令使用了多少字节,其次这是一个分支,如果是的话,是什么类型,有条件或无条件,并做出相应的反应。模拟器除了模拟寄存器之外,还完成了所有这些工作。反汇编程序将用于教育目的,而不是在 sourceforge 上进行精美的发布。足以了解如何在位级别解析指令、计算跳转偏移量。

我将从一个简单的指令集开始,例如 12 位 pic 或 6502 或类似的指令集(msp430 是另一个可能的候选者)。如果您使用现有的指令集来学习如何编写模拟器,则可以利用该 isa 的现有工具链(汇编器,也许还有编译器)。将任务分成两半。对于新的指令集,如果您想手动编码机器代码,您在某些时候将需要一个工具链,或者至少需要一个好的反汇编器(反汇编器双重检查您是否拥有您认为想要的机器代码)。或者,您可以在模拟器中选择按执行顺序输出反汇编代码,无论如何都有利于调试。

首先不要担心中断,但请注意,您将需要一种机制来停止模拟流程、保存状态并在如此多的时钟周期内重新使用模拟器。您将看到许多模拟器基本上单步执行每条指令。由于周期性中断或需要与模拟处理器同步的其他模拟硬件的硬件原因,评估每条指令的时钟滴答数。因此,最好首先以这种方式进行建模,然后根据需要提出性能改进。

如果您还没有使用状态机进行编程,我强烈建议您了解一些状态机并编写一些练习程序。

我正在开展一个项目,我希望发布该项目,如果我完成的话可能会对此类主题有所帮助。我现在的指令集模拟器实际上是用硬件设计语言(例如 verilog,不是我使用的 hdl,但它转换为 verilog)编写的,然后使用带有 C/C++ 包装器的 verilator 之类的东西。因此,与提取操作码和位相关的工作是由专门用于管理该工作的语言来处理的。想要模拟外围设备或提供图形用户界面或其他方式显示正在发生的事情的部分由为此设计的语言处理。如果您碰巧正在从事一个在 vhdl 或 verilog 中实现新指令集的项目,我强烈推荐混合 hdl 模拟器加软件解决方案,如果它是商业 hdl 模拟器,则通过 VPI;如果您使用 verilator,则通过其他更简单的方法或 icarus verilog 或 ghdl 或其他。(icarus可能需要像vpi这样的商业接口)。这里的美妙之处在于,您更接近真实的硬件,硬件中的错误/缺陷等可以在进入芯片之前找到并处理,硬件的更改或改进可以在模拟中立即实现,而不必进行匹配模拟器等方面的更改或改进。hdl 模拟器具有脚本语言或系统 C 等,这对于对硬件进行功能测试很有用,但无法在硅上运行它。如果您不鼓励使用这些工具并在模拟逻辑上运行真实的二进制文件,并为真实工具提供抽象层来加载、调试或监视(例如,向 openocd 编写后端以通过主机传递到 hdl sim 层并与芯片上的模拟 jtag 调试器进行对话,具体取决于此设计的复杂性(非常可行,因为我自己已经完成了))。这些真实的程序既可以在模拟中运行,也可以在硅片上运行,从而节省了编写测试的时间,并在硅片到达之前就编写好了测试软件,而不是在硅片到达之后才开始。

抱歉 HDL 切线。如果这是一个新的或没有工具链指令集的其他工具,您将不得不花时间在该工具链上,至少是一个汇编器和链接器,我会做某种反汇编器,然后将该反汇编器或其部分转换为第一个片段在模拟器上。就我在指令集模拟器中看到的标准事物而言,基本上是从单步角度考虑,以便您可以处理时钟和中断以及其他模拟硬件。模拟的核心功能要么模拟一个可能不是完整指令的时钟周期(状态机方法),要么核心功能模拟单个指令并返回根据指令的要求修改寄存器、标志和内存(并对模拟时钟进行计数) )。根据您希望该模拟器从一开始就实现的功能丰富程度,您可以读写 ram/rom 和寄存器功能,以便您可以在一个地方捕获内存和寄存器更改以显示给用户。仅通过这些抽象函数访问或至少修改寄存器和RAM。除此之外,它只是大量的输入,指令集越复杂,指令越多,需要输入的代码行就越多。