用于编译成自定义机器语言的工具包

Toolkits for compiling into a custom machine language

假设我构建了一个能够运行 选择基本命令的解释器(更像是一个虚拟机)。当然,我不想使用 Hex-Editor 手动构建机器代码(完全由其他架构组成,与任何其他架构都不相似)。

是否有针对此类情况的现有工具? 我在想使用某种工具将一些高级语言(如 C)编译成基本的汇编语法,但同时限制编译器仅使用选择的 asm 命令(例如仅基本的 mov、alu 命令、push/pop, 调用并跳转).

当然,一种选择是从头开始为此构建一个全新的编译器,但这显然很糟糕,感觉就像重新发明轮子一样。 另一种选择是编写一个脚本来处理生成的 asm 代码,用其他命令替换不受支持的命令(比如将 lea 拆分为 mov 和 arithmetrics),但这对于更复杂的命令来说是相当多的工作。 我想把自己的工作减少到最多编写一个汇编程序,最好是只获取选定命令子集的汇编程序(因此 none 这些花哨复杂的 x86 命令,如 ascii/bcd 算术、xchng、字符串命令甚至 lea) 来简化事情。 这甚至是一种可行的方法,还是有更简单的方法来实现我想要的? 我相信我不是第一个做这样的事情的人。 理想情况下,我需要一个可以详细描述目标架构及其功能的编译器。

有没有人做过类似的事情?我什至不知道从哪里开始,但肯定有一些工具可以帮助解决这个问题。

编辑: 明确地说,我确实在寻找为自定义 ISA 构建字节码的工具。我提到 C 作为一种高级语言,但这只是一个例子。我只是在寻找一种方法来为自定义架构编写简单的代码片段,而无需在十六进制编辑器中手动编写字节码,最好使用高级语言。我的想法是,如果我可以最小化某些标准编译器假定的指令集,我可以编写一些简单的脚本来将它翻译成我的自定义机器代码。

您想使用一些 JIT-compiling library. There are lots of them, at least on Linux: libgccjit, LLVM, libJIT, GNU lightning, asmjit,等等... libgccjitLLVM 都可以进行花哨的优化。

(我首先了解到您想为您现有的 x86-64 PC 制作一个新的编译器或 JIT bytecode 解释器)

Ideally, i would need a compiler where i can describe the target architecture and its capabilities in detail.

您可能会对 iburg(以及 GCC and/or Clang/LLVM 中的某些内部人员)感兴趣。

如果你确实在发明一个新的ISA(也许是一些低级bytecode),你可以适应并移植GCC 到它(写一个新的 machine-description 文件,等等...)。这可能需要你几个月的工作。在 gcc@gcc.gnu.org 上寻求帮助。阅读 GCC 内部结构 文档。注意 GIMPLE.

如果要幼稚,optimizing C compiler (or for a C subset) for your new bytecode, you could take inspiration from tinycc which shows that writing a naive C-like compiler from scratch is feasible quite easily (and might take less time than diving into GCC internals). But that compiler won't optimize at all ! See this.

您还应该考虑将您的语言编译为 C(并将低级优化和代码生成留给系统 C 编译器)。这是一个quite popular approach.

还要注意一旦你完全指定了一个 ISA,为它写一个汇编程序就是一个简单的练习(一旦你有了一个汇编程序,你就不需要fiddle 用十六进制的位来为你的 ISA 写一些代码)。

您可能会对 homoiconic or multi-stage programming languages. Look into Lisp -notably Common Lisp and its SBCL 实现感兴趣 - 并进入 MetaOcaml。


你的问题不清楚

(即使有新的编辑)

你在发明一种新的字节码、一种新的编程语言、一种新的 ISA 吗?

您需要阅读 SICP and The Dragon Book to at least get the good terminology and concepts (since in its initial form your question is unclear and confusing). You should also be interested by Scott's Programming Language Pragmatics and probably Queinnec's Lisp In Small Pieces


My idea was just, that if i could minimize the instruction set assumed by some standard compiler, i could write some simple script to just translate it into my custom machine code.

这可能是错误的。已经发明了一些 one instruction set computer,但实际上这些 1 指令集的实现效率不高,因此将指令集最小化为 1 并不是一个好主意。使用这样的 "one instruction set ISA" 作为中间表示(在您的编译器中)不是一个好主意。

有许多可重定位(开源)编译器。 Gcc、llvm 和许多其他的。你会发现 gcc 几乎没有用胶带和电线、大量的 PITA 粘在一起。 llvm 宣传添加后端和文档很容易,但文档太过时了,它既有帮助又有误导性和错误性。以及他们用来演示多么简单的 msp430 后端。那个后端坏了,一直都是,不想修复它...

尽管这当然是可能的,但时不时地添加后端。近年来,pdp-11 到 gnu 和 risc-v 到 gnu 和 llvm。 aarch64 等。有些人会分叉出一个特定版本的 gcc 或 llvm 并为此而努力,因为将一个后端添加到这些工具的一个版本是一项任务,如果你想上游它,你需要永远维护它的每个版本(或说服别人)。

vbcc 是我所知道的另一个,还有许多其他优化和非优化。你当然可以走自己的路。您 want/need 是像 C 这样的完全兼容的语言还是自己制作子集。

如果不需要优化,那么您可以移植现有的后端,gcc 中有一个基本上是堆栈机器,您可以从中移植或制作静态二进制翻译工具。 JAVA 是一个基于堆栈的东西,已经有人尝试用它来做同样的事情......旧的 pascal 编译器生成了类似 tcc 的东西或者他的一个类似的作品。

lcc是教科书基础的,非优化...

不幸的是,none 的主要编译器旨在通过工具简化后端。你是工具,必须努力把它推到那里,骑着那只熊,希望它能起作用……

您可以尝试接近那些做过类似于您在 cris 后端或 moxie 后端所做的事情的人,因为他们已经完成并上游,他们可能会有一些建议...