6

Javaオペコードは、iloadローカル変数配列(LVA)からオペランドスタックに値をプッシュするために使用されます。

このオペコードは、LVAのインデックスとして機能するパラメーター( en.wikipedia.org/wiki/Java_bytecode_instruction_listings )として1バイトを取ります。

LVAの1つの要素が常にオブジェクトへの参照である場合(静的メソッドの場合はそうではないと思いますが、今は無視します)、正確に1バイトがインデックスとして使用される場合(256の可能な値)、では、メソッドはどのようにして255を超える異なるローカル変数にアクセスできるのでしょうか。

4

2 に答える 2

17

はい、Java メソッドが 255 を超えるローカル変数を持つことは可能です。wideオペコード命令は、8 ビット インデックスの代わりに 16 ビット インデックスを使用するようにiloador命令を変更するために使用できます。つまり、オペコードが使用さaloadれる限り、関数内で最大 65536 個の異なるローカル変数を持つことができます。wide.

ただし、Java ローカル変数は必ずしも JVM ローカル変数と 1 対 1 で対応しているとは限りません。Java コンパイラがコードを調べて、一部のコンテキストでローカル用のスペースを再利用できることに気付き、複数の Java ローカルを同じ JVM ローカル変数にマップする可能性があります。

お役に立てれば!

于 2012-12-24T22:14:37.547 に答える
12

300 個のローカル変数を持つプログラムを作成して試してみました。このスニペット:

System.out.println(a255);
System.out.println(a256);

これにコンパイルされます:

3575: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
3578: iload         255
3580: invokevirtual #53                 // Method java/io/PrintStream.println:(I)V
3583: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
3586: iload_w       #256                // Utf8 a196
3590: invokevirtual #53                 // Method java/io/PrintStream.println:(I)V

注: Eclipse と javac でコンパイルしても、まったく同じ結果が得られます。

于 2012-12-24T22:19:25.627 に答える