1. 程式人生 > >Java千百問_02基本使用(015)_java如何通過彙編方式執行

Java千百問_02基本使用(015)_java如何通過彙編方式執行

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同目錄)。