java - 是否可以在没有外部程序的情况下用 Java 编译成机器码?

标签 java gcc assembly compiler-construction jvm

首先,这不是您的标准问题“我想将 Java 代码编译为机器代码”。

我正在开发一个用 Java 编写的编译器,它将把某种语言(在我的例子中是 Brainfuck)翻译成 x86 汇编,之后我目前正计划使用 NASM 和 GCC 来生成机器代码。

鉴于 HotSpot JVM 可以将 Java 字节码编译为机器码,我假设存在某种机制可以将 A 类源代码编译为机器码。

有没有办法在用 Java 编写的编译器中使用它?我的主要目标是探索在不依赖路径上可用的外部程序(例如 GCC 和 NASM)的情况下用 Java 编写编译器的可能性。我确实需要一个 C 编译器,因为我正在链接 cstdlib,因为我在我的 x86 汇编代码中使用这些函数。

为了澄清,我目前正在做以下事情:

  1. 将 x86 程序集写入 bf.asm 文件。
  2. 使用 nasm -f win32 bf.asm 将程序集转换为目标代码。
  3. 使用 gcc -o bf bf.obj 将目标代码与 Windows 操作系统和 cstdlib 库链接。

我正在寻找替代在第 2 步和第 3 步中使用 nasmgcc 的需要的可能性,而不是使用 Java 代码。

最佳答案

Seeing as the HotSpot JVM can compile Java bytecode to machine code, I assume there is some mechanism available to compile source code of type A to machine code.

这不成立。

JIT 编译器将 Java 字节码编译为 native 代码。它不理解 Java 字节码以外的任何东西。字节码不是“源代码”。 (它们实际上是机器代码的一种形式……用于抽象计算机……Java 虚拟机。)

简而言之,JVM 的一部分没有可用的机制来将源代码编译为机器代码。

而且,事实证明,JIT 编译器并非设计用于在文件中生成 native 代码以供其他程序使用。 native 代码以内存块中的原始机器指令的形式出现。没有符号表。无搬迁信息。可能充满了对 JVM 其他部分的硬连线调用。基本上它是为在当前运行的 JVM 中执行而设计的,而不是为其他任何东西而设计的。

Is there any way to use this in a compiler written in Java?

JIT 编译器不适用于您的问题……除非您编写编译器来生成有效的 Java 字节码。如果您这样做了,那么 JVM 就可以运行您的代码,并且 JIT 编译器会在某个时候将您的字节码编译为 native 代码。


底线:如果您的目标是生成可以作为单独的可执行文件运行或链接到单独的可执行文件的 native 代码,

  • JIT 编译器对你没用,但是
  • 您可以使用 JVM 包括 JIT 编译器作为您的执行平台,通过生成字节码,
  • 您也可以使用普通的 Java 编程来实现您的编译器或汇编器,包括一个以适合您需要的格式生成和发出 native 代码的组件。

关于java - 是否可以在没有外部程序的情况下用 Java 编译成机器码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40676925/

相关文章:

linux - 未定义的对 -finstrument-functions 的引用

c - 如何让 gcc 生成合适的代码来检查缓冲区是否充满 NUL 字节?

c - 零初始化结构未出现在内存中

java - 带有 Join 的 JPQL 更新语句

java - java中如何计算有序数组的众数

java - 握手失败客户端 key 交换,使用证书链

c++ - Visual Studio 2017 : _mm_load_ps often compiled to movups

java - 在运行时查找 java 类依赖项

c - Linux 内核中 ATOMIC_INIT 宏的用途

c# - 为什么 Console.WriteLine() 使用 ecx 寄存器,尽管 eax 和 ebx 是免费的?