Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

JVM用アセンブラJasminを触る

自分はJVMの仕様について比較的知っている方らしいということに最近気づき、バイトコードについて人に説明するためのツールとしてJVMアセンブラJasminの利用を検討。
バイトコードの理解があれば困らずに利用できるツールだと思うが、説明に使うには若干不足かも。CASL2シミュレータのようにスタックを見ながらバイトコードをステップ実行できることを期待していたのだが……。Javaプログラムとバイトコードの関連が見えるjadjdの方がまだ役に立つかもしれない。

Hello, world!

.class public Hello
.super java/lang/Object

.method public ()V
  aload_0
  invokespecial java/lang/Object/()V
  return
.end method

.method public static main([Ljava/lang/String;)V
  .limit stack 2
  getstatic java/lang/System/out Ljava/io/PrintStream;
  ldc "Hello, world!"
  invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
  return
.end method

実行時引数に渡された2つの数値を合計して表示

Javaで書くと以下のようになるが、

public class Appender {
  public static void main(String[] args) {
    System.out.println(Integer.toString(
        Integer.parseInt(args[0]) +
        Integer.parseInt(args[1])
    ));
  }
}

Jasminならこう。

.class public Appender
.super java/lang/Object

.method public ()V
  aload_0
  invokespecial java/lang/Object/()V
  return
.end method

.method public static main([Ljava/lang/String;)V
  .limit stack 4
  getstatic java/lang/System/out Ljava/io/PrintStream;
  aload_0
  dup
  ; stack: PrintStream, String[], String[]

  iconst_0
  aaload
  invokestatic java/lang/Integer/parseInt(Ljava/lang/String;)I
  swap
  iconst_1
  aaload
  invokestatic java/lang/Integer/parseInt(Ljava/lang/String;)I
  ; stack: PrintStream, int, int

  iadd
  invokestatic java/lang/Integer/toString(I)Ljava/lang/String;
  ; stack: PrintStream, String

  invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
  return
.end method