C语言中的ARM11仿真器

时间:2014-06-03 16:04:35

标签: c arm emulation pipeline

我正在尝试编写一个模拟ARM二进制文件执行的C程序。 那么它现在做了什么,我们从二进制文件中获取指令到uint32_t数组,然后我解码并执行。

问题是我只使用程序计数器从数组访问int,然后我增加它。但是对于采用偏移的分支指令,将其扩展到32位并将其添加到PC,PC应该比正在执行的指令提前8个字节。 所以应该发生管道效应。基本上就是这样:

  1. 从内存中提取32位(4字节)指令
  2. 指令已解码
  3. 执行解码指令
  4. 因此,当在管道顶部执行指令时,正在获取的指令是存储器中的两个指令。因此,PC比正在执行的指令的地址大8个字节。

    有人知道如何轻松实现该管道吗? 我想我需要为指令重做我的内存存储,因为它现在只是一个固定大小的数组。 我的想法是对齐内存,然后在每条指令后向PC添加4,并通过使用指向数组中第一个元素的指针并向其添加PC来访问下一条指令。如果这样可行,有人可以告诉我它会是什么样的吗?

1 个答案:

答案 0 :(得分:1)

您不需要模拟管道。 ARM在硬件中一段时间​​没有使用过2个管道,它们也模拟了前面的2个。

我在我的所做的是在任何时候将PC保持在前面,然后在获取我在pc-4上获取然后添加4.任何可以修改pc的指令都必须有一个if pc然后pc + = 4。当我计算一个分支时,我必须添加另一个4.为什么我这样做,我不知道。

或者,您可以将电脑指向当前指令。每次读取电脑都会添加8.可能更简单。我使用函数抽象我的指令获取,存储器读/写和寄存器读/写,并且在read_register()函数中我将添加if r15然后结果+ = 8;然后返回。

再一次,为什么我没有这样做,我不记得了,我不得不破解它以使它工作。现在的事实是我的拇指(v1)模拟器不是手臂所以它是+2而+4不是+4和+8。并且根本没有手臂模式(由我的模拟器支持),所以只有一些拇指指令可以实际修改电脑,这样就更容易只针对if reg == 15。

如果你真的想做一个arm11模拟器,你需要考虑拇指模式,然后处理电脑前面的4或前面的8,并记得在拇指模式下剥离电脑的lsbit一些必须将lsbit设置为切换到或保持在拇指模式的指令。幸运的是arm11不支持thumb2然后它变得非常难看,因为它是可变的指令长度而你必须提前两个指令而不仅仅是4或8个字节(前面可能是4,6或8个字节,你必须将接下来的两个字节解码为找出拇指模式)。如果您不想支持拇指模式,您可以轻松地查找以bx或pop设置的lsbit,然后声明您不支持拇指模式并拯救。

您的选择是模拟管道,或者您必须插入一个或一些如果reg == 15然后......代码行,并且您必须在使用pc的任何地方执行此操作(将所有寄存器读取路由到一个函数是一个非常简单的方法来做到这一点)。我应该去修理我的模拟器来做到这一点。如果您最终支持拇指模式,那么您可以简单地说是否在拇指模式下然后在此读取寄存器功能中添加4 else add 8。