从头开始构建自定义机器代码

时间:2011-06-09 05:57:38

标签: machine-code

我最近开始使用逻辑级设计作为业余爱好者,但现在发现自己遇到了软件,我不太能胜任。我已经完成了基于Etienne Sicard的论文“A Very Simple Microprocessor”在Logisim中设计一个定制的4位CPU。现在它完成了我内置的非常有限的功能(添加,逻辑AND,OR和XOR)而没有任何可检测到的错误(交叉手指)我遇到了为它编写程序的问题。 Logisim具有将十六进制数字脚本导入RAM或ROM模块的功能,因此我可以使用自己的微指令代码为其编写程序,但我从哪里开始?我完全处于最基本的软件设计水平,并不知道从哪里开始。有关资源的任何好的建议,以了解这个低水平的编程或我应该从这里尝试的建议?非常感谢,我知道这可能不是这个论坛上有史以来最直接适用的问题。

3 个答案:

答案 0 :(得分:0)

我不知道你提到的那篇论文。但是如果您设计了自己的自定义CPU,那么如果您想为它编写软件,您有两种选择:a)将其写入机器代码,或b)编写自己的汇编程序。

显然我会选择b。这将要求您稍微换档并进行一些高级编程。您要编写的是在PC上运行的汇编程序,并将一些简单的汇编语言转换为您的自定义机器代码。汇编程序本身将是一个高级程序,因此,我建议使用擅长字符串操作和二进制操作的高级编程语言编写它。我会推荐Python。

你基本上希望你的汇编程序能够读取这样的文本文件:

    mov a, 7
foo:
    mov b, 20
    add a, b
    cmp a, b
    jg foo

(我刚刚制作了这个程序;这是胡说八道。)

并将每行代码转换为该指令的二进制模式,输出二进制文件(或者可能是hex文件,因为您说您的微控制器可以读取十六进制值)。从那里,您将能够将程序加载到CPU上。

所以,我建议你:

  1. 提出(在纸上)一种汇编语言,它是您的机器支持的每个操作码的简单书面表示(您可能已经这样做了),
  2. 学习简单的Python,
  3. 编写一个Python脚本,一次读取一行(sys.stdin.readline()),确定它是哪个操作码以及它需要的值,并将相应的机器代码输出到stdout。
  4. 使用汇编语言编写一些将在CPU上运行的汇编代码。
  5. 听起来像一个有趣的项目。

答案 1 :(得分:0)

因为你的指令集很小,并且基于mguica答案中的线程,我会说下一步是继续和/或完全测试你的指令集。你有旗帜吗?你有分支说明吗?现在只需手动生成机器代码。标志很棘手,特别是溢出(V)位。你必须检查进位并在msbit加法器上执行以使其正确。因为指令集足够小,你可以尝试背对背指令的各种组合,然后依次为xor,然后是xor,然后是add,或者后面跟着xor等,然后在分支中混合。回到标志,如果xor和/或者例如没有触摸进位和溢出那么请确保你看到进位和溢出为零并且没有被逻辑指令触及并且进位和溢出是一个而没有触及,并且还独立地显示进位和溢出是分开的,一对一关闭,没有被逻辑触及等等。确保所有条件分支仅在该条件下操作,引入具有在两个状态中被忽略的标志位的各种条件分支,以确保条件分支忽略他们。还要验证条件分支是否应该修改它们不是。同样,如果条件不会导致分支不触及条件标志......

我喜欢使用随机化,但它可能比你更多的工作。我喜欢独立开发一个指令集的软件模拟器,我发现它更容易使用,逻辑有时也更容易在批量测试中使用。然后,您可以随机化一些简短的指令列表,改变指令和寄存器,自然地手动测试测试仪的一些结果,测试完成后的寄存器状态和标志位的状态。然后使这个随机列表更长,在某些时候你可以采用一个长指令列表并在逻辑模拟器上运行它,看看逻辑是否提供了与指令集模拟器相同的寄存器结果和标志位,如果它们改变了数字输出为什么。如果不尝试另一个随机序列,另一个。在开始测试之前使用素数填充寄存器是一个非常好的主意。

回到单独的指令测试和标志遍历所有角落情况0xFFFF + 0x0000 0xFFFF + 1,这样的事情只是放在操作数的右侧和右侧,结果是一个标志远离标志变化的位置旗帜改变的地方,以及旗帜的另一面。对于逻辑,例如,如果他们使用零标志,那么有各种数据模式,测试结果位于零0x0000,0xFFFF 0xFFFE 0x0001 0x0002等的任何一侧,等等。也许一个步行的结果也是0x0001结果0x0002,ox0004等等。

希望我理解你的问题并且没有指出你到目前为止已经做过的显而易见的事情。

答案 2 :(得分:0)

我做了类似的事情,您可能会觉得有趣。我还从头开始创建了自己的CPU设计。它是基于哈佛架构的8位多周期RISC CPU,具有可变长度的指令。

我从Logisim开始,然后用Verilog编码所有内容,并在FPGA中进行了合成。

为回答您的问题,我完成了一个简单且基本的汇编程序,该程序将程序(指令,即助记符+数据)转换为相应的机器语言,然后可以将其加载到PROG内存中。我已经用shell脚本编写了它,并使用了awk,这让我很满意。

我基本上执行两遍操作:首先将助记符转换为它们对应的操作码,然后将数据(操作数)转换为十六进制,这里我会跟踪所有标签地址。第二次通过会将所有标签替换为其相应的地址。 (标签和地址用于跳转)

您可以在此处查看所有项目,包括汇编器:https://github.com/adumont/hrm-cpu