我有兴趣了解如何在没有像 unix 系统调用这样的高级函数的帮助下编译/创建一种非常简单的语言(即 Brainfuck)。我想用一些依赖于 CPU 的低级汇编语言编写一个编译器,这样我就可以用简单语言提供源代码并最终得到二进制文件。不确定这是否清楚,但基本问题是如何在不借助硬件中尚未存在的任何内容的情况下将源代码转换为二进制文件。
编辑:更简洁的问题陈述...
给出:
-硬件(主板/CPU等)
未给出:
-UNIX/DOS
-C/FORTRAN/任何其他语言
我将如何实现像 Brainfuck 这样的简单语言?
我知道有更多实用的编译方法,但出于教育目的我对此很感兴趣。
抱歉,如果这个问题是多余的或明显的 - 我不是计算机科学家,所以也许我只是不知道在线找到问题解决方案的正确词汇。如果有人可以提供有关该主题的链接或文本,我们将不胜感激。
最佳答案
看看维基百科上的描述,这并不是一件困难的任务。我仍然可能会用某种你知道的语言开始,也许你喜欢,也许不喜欢。 C是一个不错的选择。文件 I/O 是一个小型或大型项目,具体取决于平台等。稍后再担心,在该语言的“源代码”中进行编译。对于该源中的每个角色,执行任务
> ++ptr;
< --ptr;
+ ++*ptr;
etc
然后将其转换为汇编。你只需要一个寄存器来保存ptr,几行asm来初始化数组/ram并将寄存器/ptr设置到开头。另一个寄存器来浏览源代码。如果你只寻找 8 个字符,你可以使用 if-then-else 来遍历这些字符,除非有一些位模式可以使它们更容易处理。如果你愿意,你可以创建一个 256 字节的查找表,并将其用作该指令的处理程序的地址,或者将它们转换为 0-7 之间的整数,然后在跳转表中使用它,等等。
这是一个解析器,不一定是编译器。我会用 C 或某种高级语言编写编译器,它接受一个字节数组,即程序,对于输出实现该指令的 asm 源代码的每条指令,您在输入、输出上得到一个小于字节(使用 ARM asm)
add r0,#1
减号
ldr r1,[r0]
sub r1,#1
str r1,[r0]
r0 是 ptr 寄存器,r1 只是帮忙。
如果您确实反对使用像 printf 这样的调用,那么请将此代码的输出设置为字节数组,这些字节数组是 asm 源输出的每个字符 a、d、d、空格、r、0、逗号的 ascii 、#、1、cr、lf 等。用汇编语言和一些高级语言相当容易实现。如果你想直接转为二进制,那么只需输出机器代码,就更容易了。
将源字符串放入此编译器并将输出放入稍后可以执行的某个文件中可能需要系统调用。如果您在同一平台上运行,并且可以执行自修改代码,即在某个地址构建机器代码,然后在完成解析后跳转到该地址执行,则可以避免输出成为文件。
写这个答案所花费的时间比用 C 或 asm 实现解决方案花费的时间要长很多倍。您遇到的具体困难是什么?
关于compiler-construction - 从硬件编写低级语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10492079/