1、java如何通过汇编方式运行
java本身不能通过汇编方式运行。但是,我们可以通过某些插件,在运行中将java代码解释为汇编指令,让我们能够通过分析执行的汇编指令来查找一些问题,也可以帮助我们分析和理解JVM是如何解释和编译的(当然java本身的编译和运行和汇编无关)。
PrintAssembly是JVM的一个运行参数,它允许我们获取在控制台打印java代码翻译成的汇编指令。使用PrintAssembly需要一些插件的支持,这些并不是JVM直接提供的,Kenai项目则提供了可用的插件(下载 https://kenai.com/projects/base-hsdis/downloads )。根据不同的环境下在对应的指令集。本人是mac系统,所以下载了hsdis-amd64.dylib。
下载后需要将hsdis-amd64.dylib放在$JAVA_PATH/jre/lib/server/中,与libjvm.dylib同目录。
之后我们就可以通过指定运行参数来运行我们的代码:
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly TestHsdis
例子:
public class TestHsdis {
public static void main(String[] args) {
System.out.println("1");
}
}
编译运行时加入-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly,结果如下:
Java HotSpot(TM) 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
Loaded disassembler from /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/jre/lib/server/hsdis-amd64.dylib
Decoding compiled method 0x000000010b4fd710:
Code:
[Disassembling for mach=‘i386:x86-64‘]
[Entry Point]
[Constants]
# {method} {0x000000011f270fc8} ‘hashCode‘ ‘()I‘ in ‘java/lang/String‘
# [sp+0x40] (sp of caller)
0x000000010b4fd880: mov 0x8(%rsi),%r10d
0x000000010b4fd884: shl $0x3,%r10
0x000000010b4fd888: cmp %rax,%r10
0x000000010b4fd88b: jne 0x000000010b445e20 ; {runtime_call}
0x000000010b4fd891: data32 data32 nopw 0x0(%rax,%rax,1)
0x000000010b4fd89c: data32 data32 xchg %ax,%ax
....
2、PrintAssembly is disabled是什么原因
我们在加入参数-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly运行时,可能会报如下错误:
Java HotSpot(TM) 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
Could not load hsdis-amd64.dylib; library not loadable; PrintAssembly is disabled
原因是对应的hsdis-amd64插件没有放入指定路径,导致运行时无法加载。我们一定要将hsdis-amd64.dylib放在$JAVA_PATH/jre/lib/server/中,与libjvm.dylib同目录(mac系统,如果是linux放在与libjvm.so同目录)。