21

学術研究のためにJavaのサブセットを実装しようとしています。さて、私は最終段階(コード生成)にあり、メソッド引数がどのように処理されるかを確認するためのかなり単純なプログラムを作成しました。

class Main {
    public static void main(String[] args) {
        System.out.println(args.length);
    }
}

それから私はそれを構築し、次の場所で見つけたオンライン逆アセンブラを介して「Main.class」を実行しました: http ://www.cs.cornell.edu/People/egs/kimera/disassembler.html

'main'メソッドの次の実装を取得します:(分解された出力はJasminにあります)

.method public static main([Ljava/lang/String;)V
    .limit locals 1
    .limit stack 2

    getstatic   java/lang/System/out Ljava/io/PrintStream;
    aload_0
    arraylength
    invokevirtual   java/io/PrintStream.println(I)V
    return
.end method

これに関する私の問題は次のとおり
です。1。aload_0「this」をスタックにプッシュすることになっています(JVM仕様が言っているようです)
2。arraylength参照がスタックの一番上にある配列の長さを返すことになっています

したがって、私によれば、1と2の組み合わせは機能しないはずです。

それはどのように/なぜ機能していますか?または、逆アセンブラにバグがあり、実際のバイトコードは別のものですか?

4

1 に答える 1

51

aload_0は「this」をスタックにプッシュすることになっています

完全ではありません…メソッドの最初の参照引数(または、より一般的には最初のローカル参照変数)をaload_0読み取り、それをスタックにプッシュします。

メンバー関数では、最初のローカル変数がたまたまthis参照になります。

ただし、mainはメンバー関数ではなく、静的関数であるためthis引数はなく、メソッドの真の最初の引数はですargs

于 2011-01-09T20:05:55.647 に答える