Java中的内联ASM

自从我开始在Java中嵌入asm用于Intel x86 64位处理器的小项目并无缝运行和编译这些方法(并且可能稍后将这些调用模拟为后退)时,我想知道是否存在已经存在的x86编译器的Java实现。 我也想要支持这些高级指令。

目标是最终有类似的东西:

public int myJavaMethod(long value) { doSomeJavaStuff... int result = 0; asm(" push eax", " mov eax, value", " cmp eax, 0", " jne notEqual", " mov result, 1", " jmp done", "notEqual: mov result, 0", "done: pop eax"); doSomeMoreJavaStuff(); return result; } 

是)我有的:

  • 英特尔的OPCodes和架构手册(VOL2)
  • 我正式使用JNA编译并运行asm(“nop”)程序部分

目前的挑战:

由于任务的性质,我将尝试访问底层JavaVM堆栈帧 – 这是可能的(记住你得到esp堆栈指针和基本指针ebp,即使是ret op将放在eip指针中的地址)但是将解决方案与某个java VM +构建目标结合起来,我没有遇到任何问题,因为可以创建各种目标适配器并在JavaVM实现中进行探讨将是有趣和有趣的。

上述基于字符串的解决方案的问题在于参数和结果的处理。 可能有必要提供参数映射,如asm(params(result,value,whatever),“opcodes”),并将输出变量直接放在正确的内存槽或JIT用于填充params调用中的变量的寄存器中或者执行类似result = asmResult(result)的操作,从asm调用的数据部分读取实际更改的值,并将其放在正确的值中。

通过对这些信息使用Unsafe,甚至可以访问Object和Class变量并导航这些值,从而获得asm代码中使用的所有引用的地址和类型。 因此,在不干扰Java的情况下使用asm(“mov eax,super.field”)是可能的 – 除非JIT再次对寄存器缓存进行一些有趣的优化,但可能不太可能,因为asm(…)是一个特定的调用和缓存对象变量内容可能违反有关对象的并发条件。 但对于Oracle的JVM开发人员来说,这又是一个问题。

因此,如果您有任何有关现有Java代码或C代码的信息可以帮助我做这样的事情,欢迎您。

最好的帮助是x86编译器的Java实现,它已经有一些方法可以在一系列字节(操作码)中转换某些asm结构,所以我可能会从上面的调用和信息中创建一个真正的ASM方法。通过检查方法字节代码以及Unsafe和任何信息源来收集。

最后,我想在我的Java代码中编写汇编程序而不需要详细编写c / ASM,为不同的操作系统和平台加载库。 没有意义。 一旦这个工作,可以轻松地按需生成“C”函数调用,甚至可能绕过JNA摆脱另一个依赖。

因此,如果您知道代码和项目或有其他信息,欢迎您。

[更新]

这个问题不针对JNI / JNA。 目标是简单地绕过使用外来编译器并加载库。 这个想法只是直接从Java内部编译到内存中,并通过使用指向它的指针以及一些用于参数和值处理的附加数据来启动方法。

只要想想这个工作流编写C / ASM,使用gcc编译,loadLibrary,JNA调用方法进入工作流程编译(使用Java)进入内存,通过JNA调用方法。 我已经可以做到这一点我只想使用更多的操作码而不创建我自己的编译器前端。 这不是关于这是否可能,而是关于如何懒惰地做。

但是,一旦我certificate了基本的可行性,我猜人们会加入更多的目标平台(我只针对Linux和i5 + Intel Xeon v3处理器)。

[更新2]

目前,我正在研究NASM编译器,因为它被认为是一个使用Intel表示法的优秀且积极开发的编译器。 我已经向开发人员询问了如何实现透明,简单和快速(例如无磁盘访问)集成。 如果这有效,那么使用流行的编译器为C创建类似的解决方案也是可能的。

想法是在eclipse中编辑Java源代码,运行程序完成。 使用不同语言编写这些片段以及调用和所有其他乐趣应该是完全透明的。

我不知道你怎么能这样做。 我认为你在这里遗漏了很多东西,首先想到的主要问题是:

  • Java编译为字节码,这与英特尔的组合无关。 JVM是基于堆栈的机器,而Intel CPU(主要)是基于寄存器的。
  • Java无法直接访问硬件或系统调用,因为它在VM上运行,而大多数内联汇编都是为此目的。
  • 不会在非英特尔CPU中运行(但我想你已经考虑过这个),如果你计划进行系统调用,你可能还需要针对特定​​的操作系统,这会打败主要的一个(忘记了) )Java的目标。
  • 您可能需要一个自定义JVM才能直接运行本机指令。

这在理论上是可行的,但绝对不是一件小事。

如果您的意思是英特尔汇编程序或Java模拟器,那就是另一个故事。