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

时间:2019-01-05 17:27:53

标签: assembly virtual-machine machine-code

可以说我建立了一个解释器(更像是一个虚拟机),能够运行一些基本命令。自然,我不希望使用十六进制编辑器来手动构建机器代码(它完全组成并且与其他任何体系结构都不相似)。

有没有针对这种情况的预先存在的工具? 我当时想使用某种工具将诸如C之类的高级语言编译成基本的汇编语法,但同时又限制了编译器仅使用部分asm命令(例如仅基本的mov,alu命令,push / pop) ,调用并跳转)。

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

有人做过类似的事情吗?我什至不知道从哪里开始,但是肯定必须有一些可用的工具来帮助实现这一目标。

编辑: 为了明确起见,我确实在寻找工具来为自定义的ISA构建字节码。我提到C是一种高级语言,但这只是一个例子。我只是在寻找一种为自定义体系结构编写简单代码片段的方法,而无需用十六进制编辑器(最好使用高级语言)手工编写字节码。我的想法是,如果我可以最小化某些标准编译器假定的指令集,则可以编写一些简单的脚本,将其转换为自定义的机器代码。

2 个答案:

答案 0 :(得分:2)

有许多可重新定位的(开源)编译器。 Gcc,llvm等。您会发现gcc几乎不与胶带和捆扎线(巨大的PITA)固定在一起。 llvm宣传可以轻松添加后端和文档,但该文档过时了,以至于容易引起误解和错误。还有他们用来演示的msp430后端多么简单。后端坏了,而且一直都没有,也不想修复它...

尽管肯定有可能,但不时地添加后端。近年来,pdp-11到gnu,risc-v到gnu和llvm。 aarch64等。有些人会派生特定版本的gcc或llvm并为此工作,因为将一个后端添加到这些工具的一个版本是一项任务,如果要上游,则需要永久维护每个版本(或说服其他人)。

vbcc是我所知道的另一个,还有很多,优化而不是。您当然可以走自己的路。您是否想要/需要像C这样的全面兼容的语言,或者自己制作一个子集。

如果不需要优化,则可以移植现有的后端,gcc中的后端基本上是一台堆栈计算机,您可以移植或使用它来制作静态二进制转换工具。 JAVA是基于堆栈的,已经有一些尝试对它进行相同的操作...旧的pascal编译器生成了类似tcc或类似代码的东西。

lcc是一本基于教科书的非优化课程...

不幸的是,没有一个主要的编译器旨在通过工具简化后端。您是工具,必须努力将其推入其中,骑着那只熊,并希望它能起作用...

您可以尝试与做过与cris后端或moxie后端相似的工作的人接触,因为这些人已经完成并处于上游,他们可能会提供一些建议...

答案 1 :(得分:0)

您想使用一些JIT-compiling库。它们很多,至少在Linux上:libgccjitLLVMlibJIT,GNU lightningasmjit等…两者 libgccjit LLVM 可以进行优化。

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

  

理想情况下,我需要一个编译器,在其中可以详细描述目标体系结构及其功能。

您可能对iburg(以及GCC和/或Clang / LLVM中的某些内部组件)感兴趣。

如果确实是在发明新的ISA(也许是一些低级别的bytecode),则可以改编并移植GCC到它(编写新的machine-description文件等)。这可能需要您花费几个月的时间。在gcc@gcc.gnu.org上寻求帮助。阅读GCC internals文档。请注意GIMPLE

如果您想为新的字节码使用朴素的optimizing C编译器(或C子集),则可以从tinycc那里获得启发,它表明从头开始编写一个天真类似于C的编译器是很容易实现的(并且可能比进入GCC internals花费的时间要少)。但是那个编译器根本不会优化!参见this

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

还请注意,一旦您完全指定了ISA,并为其编写了一个汇编程序就是一个简单的练习(并且一旦有了汇编程序,就不需要在其中进行任何操作了。十六进制为您的ISA编写一些代码。

您可能对homoiconicmulti-stage programming语言感兴趣。研究Lisp,尤其是Common Lisp及其SBCL的实现,并研究MetaOcaml。


您的问题不清楚

(即使有新的修改)

您要发明新的字节码,新的编程语言,新的ISA吗?

您需要阅读SICPThe Dragon Book才能至少获得良好的术语和概念(因为在最初的形式中,您的问题不清楚且令人困惑)。您还应该对Scott的Programming Language Pragmatics以及Queinnec的Lisp In Small Pieces感兴趣。


  

我的想法是,如果我可以最小化某些标准编译器假定的指令集,那么我可以编写一些简单的脚本,将其转换为我的自定义机器代码。

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