我正在编写一个模拟ARM二进制文件执行的C程序。现在,我们将二进制文件中的指令提取到uint32_t数组中,然后对其进行解码和执行。
问题是,我只使用程序计数器从数组访问it,然后增加它。但是对于分支指令,这需要偏移量,将其扩展到32位,并将其添加到PC,PC应该比正在执行的指令提前8个字节。因此,管道效应应该发生。这基本上是:
因此,当指令在流水线顶部执行时,正在获取的指令是内存中的两条指令。因此,PC比正在执行的指令的地址大8个字节。
有谁知道如何轻松地实现这条管道吗?我想我需要为指令重做内存存储,因为它现在只是一个固定大小的数组。我的想法是对齐内存,然后在每条指令之后向PC添加4,然后使用指向数组中第一个元素的指针访问下一个指令,并将PC添加到其中。如果能成功的话,谁能给我看看那会是什么样子?
发布于 2014-06-04 00:38:54
你不需要模拟管道。ARM已经有一段时间没有在硬件上使用2位超前管道了,他们也模拟了前面的2条。
我在我的电脑里所做的是,在修改后的任何时候都要保持pc 1的领先,然后在pc上取- 4然后添加4。任何能够修改pc的指令都必须有一个if pc然后是pc+=4。当我计算出一个分支时,我必须再添加4个。我为什么要这样做,我不知道。
或者,您可以让pc指向当前指令。每次阅读pc时,你都会添加8,这样可能更容易。我使用函数抽象我的指令提取、内存读写和注册读/写,并在read_register()函数中添加if r15然后result+=8;然后返回。
再说一遍,为什么我不这么做,我不记得了,我不得不黑它来让它工作。现在我的现实是一个拇指(V1)模拟器而不是arm,所以它是+2和+4不+4和+8。而且根本没有arm模式(由我的模拟器支持),所以只有几个指令集才能真正修改pc,这样就更容易只针对那些使用if reg==15的人。
如果你真的想要做一个arm11模拟器,你需要考虑拇指模式,然后处理pc要么提前4,要么提前8,并记住在拇指模式下将lsbit从pc上删除,当它被一些指令修改时,必须将lsbit设置为切换或保持拇指模式。幸运的是,arm11不支持thumb2,然后它变得非常难看,因为它是可变的指令长度,您必须在前面有两个指令,而不仅仅是4或8个字节(可以是前面的4、6或8字节,您必须对后面的两个字节进行解码才能在拇指模式下找到)。如果你不想支持拇指模式,你可以很容易地查找在bx或pop中设置的lsbit,然后声明您不支持拇指模式并退出。
您的选择是要么模拟一个管道,要么您必须插入一个或一些如果reg==15然后.代码行,您必须在使用pc的任何地方都这样做(将所有寄存器读取路由到一个函数是一种非常简单的方法)。我应该去修理我的模拟器来做这个。如果您最终支持拇指模式,那么您可以简单地说,如果在拇指模式,然后添加4个其他添加8在这个读取寄存器功能。
https://stackoverflow.com/questions/24019818
复制相似问题