第10章スタックとローカル変数の操作

10.1定数スタッキングがある
操作を一定のプッシュ操作を実行するためのコードの多く。オペランドが直ちにオペレーションコードを以下のように、暗黙的に内部操作コードに含まれる定数値、バイトコードストリーム内の一定値:オペコード定数プッシュ操作を実行する前に、次の3つの方法は、一定の値を指定しました定数または定数プールから取られました。

スタックの一定のタイプと値を示すいくつかの自己オペレーションコードは、例えば、Java仮想マシンに通知iconst_1でオペコードは、スタック圧力人のINT番号のタイプです。Java仮想マシンは、異なる種類のデータのためにこれらのオペコードのいくつかを定義することが多い様々なスタックの人々の圧力です。命令に対してからオペランドをフェッチまたはストリーム定数プールバイトコード方向付け、上記命令は、冗長命令であるが、それらはより効率的です。これらの命令が唯一のバイトストリーム内のスペースの1つのバイトを占有しているので、彼らは効率のバイトコードを改善し、雪のサイズより少ないバイトコード。表10-1に示すように、スタックint型フロートオペコード値に対するヒト圧力。

圧入int型フロート占表10-1に示すオペコード、INT、及びフロートのワード長です。各Javaスタック場所の長さは、ワード長(少なくとも32ビット幅)です。このように、各時間プレス型フロートint型の人やスタックは、それが位置を占めます。

表に示すように、10-2長いと、二重の圧力値を人を見つけるために、オペレーションコード。長いと二重値は64ビット長です。長いまたはダブルスタック型の値は、2つの位置を占めることになるプレス人、ある時はいつでも。

別のオペレーションコードは、スタックに一定の暗黙宣言することができます。表10-3に示すように、人にヌル・オブジェクト参照型スタック圧のaconst_nullオペコード。

上述したように、オブジェクト参照の形式は、特定のJava仮想マシンの実装に依存します。オブジェクト参照は、ガベージコレクションヒープJavaオブジェクトをポイントにその素晴らしい名前を築くかもしれません。任意の有効なオブジェクト参照変数に現在いない主題を示すために、空のオブジェクトの基準点。ヌルオブジェクト参照変数fに割り当てられたプロセスがaconst_nuliオペコードを使用します。

表10-4に示すように、人に整数定数圧のための2つのオペコードは、操作直後のコードを使用して、データタイプと短い、これら二つの動作の有効範囲内の整数定数のバイトの値をスタックオペランドのコードの後に​​明示的に指定された定数は、スタックにプッシュします。すぐにオペコードバイト以下、または人々が圧力を積み重ねる前に、short型はint型の値に拡張されます。実際には、スタック操作にプッシュし、int型の値は、スタック操作の上部に短いタイプのバイトの値を置き換えます。

 

表1に示す3つの動作コードとして10-5次に押下される人々はスタック定数プール内の定数から取り出します。これらのオペコードは、対応する定数プールエントリを見つけるために、指定されたインデックスを通じてオペランド定数プールインデックス、Java仮想マシンを使用して、これらの定数の値の型を決定し、それらを人々のスタックを押してください。

 

定数プールインデックスは、バイトストリームにオペコードのすぐ後ろに、以下の、符号なしの値です。ldc_wのLDCと2ワードオペレーションコードアイテムのスタックに、またはそのINT、float型の値、またはString型のオブジェクト参照です。IDCとldc_w含む差:LDC指数つのみ語長があるので、それは唯一の定数プール内1-255を指すことができる位置の範囲内(定数プール位置0は使用されません)。そして2つのバイトの長さ、したがって、それは定数プールの任意の位置を指すことができるldc_wインデックスがlong型またはdouble型(長さバイト2を占める)を含みます。表10-5に示すように、オペコードを見て除去人間の定数プールから一定圧力。


すべてのJavaソースコードの文字列リテラルは、最終的には定数プールのエントリとして格納します。同じアプリケーションの複数のクラスが同じ文字列リテラルを使用する場合は、テキストは、クラスファイル内でそのクラスのすべてを使用するために、文字列に表示されます。例えば、文字列リテラル使用して三つのクラスがある場合は、「Harumphが!「そして、この文字列は、クラスファイルの3つの定常プールに表示されます。この方法は、との点にこれらのクラスやldc_w命令Idcとを使用することができます」Harumphスタックに!「のStringオブジェクトの参照値。

第8章で説明したように、Java仮想マシンStringオブジェクトを処理するのと同じ手順と同じ文字内のすべてのテキスト文字。言い換えれば、次のような文字列リテラルで複数のクラス、使用している場合は「Harumphを!」、Java仮想マシンは、唯一の「Harumphは!」文字列は、すべての文字列リテラルの値を表すためにオブジェクトを作成する必要があります。

仮想マシンは、文字列リテラル定数プールエントリを解析すると、「拘留」の文字列。まず、仮想マシン・チェック文字列順に文字がすでに拘留されています。もしそうなら、仮想マシンは、参照文字列が同じの親権を持って使用します。そうでなければ、それは新しいStringオブジェクトへの参照の拘留に文字列のコレクションに追加された、新しいStringオブジェクトを作成し、その後、この新しい文字列への参照が拘禁されている割り当てます。

10.2一般的なスタック操作

ほとんどの命令のJava仮想マシンの命令セットは、特定のタイプを扱うが、ありますが、いくつかの命令は見つけるための操作の種類に依存することができます。第5章に記載されているように、一般的な(非タイプ)命令は、値を分解するために使用することができない二つの単語の長さです。表10-6に示すこれらの命令。

 

 

スタックに10.3ローカル変数

int型とfloat型スタックローカル変数の型圧力人々のためのいくつかの操作コード。いくつかのオペコードは、暗黙的に一般的に使用されるローカル変数の位置を指します。例えば、iload_0ローカル変数int型は、位置0に読み込みます。他には、ローカル変数、ローカル変数のインデックスでしたが、すぐに人のオペコード位置オペコードスタック圧力以下の最初のバイトから読み取ります。

表10-7に示されるフロートとint型のヒトスタックローカル変数圧力演算コード。

表10-8リスト長命令の種類や人々のローカル変数、スタック圧力のダブルタイプ。これらの命令は、オペランドスタックローカル変数スタックフレーム部からのセグメントのワード長にデータを移動します。

ローカル変数スタックフレームから動くオブジェクト参照(フットプリントのワードサイズ)セグメントにスタック上にローカル変数最後の人オペコードオペランドセグメントグループ。これらのオペコードを表1に示す。10-9

ローカル変数に割り当てられている10.4ポップ上部スタック素子、

スタックにプッシュ点で各操作コードのローカル変数は、対応するポップトップ要素を検索し、ローカル変数の操作コードに格納することがあります。イジェクト操作は、人々のスタック操作がやり方を表す「負荷」を「保存」して行わオペコードニーモニックオペコードニーモニック圧力によって行われます。表10-10示すローカル変数オペコードのオペランド型及びfioat int型の値と格納を上から見てポップ。ワード長の値 - これらのオペコードは、ローカル変数のスタックの一番上から移動します。

10.5ワイド命令

符号なし8ビットのインデックスのローカル変数(後続命令がインデックスをILOADように)、メソッド内のローカル変数の数は256以下に制限されます。広い単一の命令は8ビットで拡張8ビットのインデックスとすることができる65,536にその限界にローカル変数の数を拡張することができます。他の改変広いオペコードオペコード。命令を使用して、広い命令は、フロント等ILOADとして符号なし8ビットのインデックスのローカル変数を、実行することができます。オペレーションコードとローカル変数の広い修飾オペコード符号なし16ビットのインデックスポイントを次の次の2バイトです。

表10-13リスト(2つの例外を有する)広い動作コードを修正することができるすべてのコマンドを2つの命令例外(IINCおよびRET)は、後のセクションで説明します。IINCコマンドとその広い変数は第12章で説明します。RET命令とその広い変数は第18章で説明しました。

ワイドオペランド転送の - 認証シーケンスは、広いバイトコード命令、変性広い命令オペコード外観等を含む場合。命令をジャンプして、直接ジャンプ命令が広いオペコード上で変更することはできません。例えば、バイトストリームには、以下の命令シーケンスが含まれている場合

広い257 ILOAD

そして、この方法のバイトストリームのシーケンスは、他のオペコードが直接ILOADオペコードにジャンプすることはできません。この場合、ILOADオペコードは常に広いオペランド命令コードとして実行する必要があります。

ソースファイルとスタックフレーム0からローカル変数にjavacコンパイラ|場所が局所的にハロ、スタックフレーム2及び3の位置にBである、fiboNumは位置4及び5中に入れました。たび連続計算フィボナッチ数、javacコンパイラはfiboNum変数にこの番号を保存します。4位と5位内のローカル変数に保存されているオングフォームタイプ値|したがって、時の動作は、フィボナッチ数列を見つけるでしょう。

長い貯蔵型の値が第1の位置、第二位置にあるガオビット(32〜63)に格納された2つの、より低い(0〜31)に分割され、注目され得ます。例えば、可変位置4に記憶されている、低fiboNumローカル変数、ガオビットは位置5におけるローカル変数に格納されています。同様に占オペランドは、long型の値がスタックにプッシュされたときに、より低いスタックにプッシュすることが最初に、次いで次のハイレベルになります。

これは長い道のり型の値だけ保留ローカル変数に実装されたJava仮想マシンのシミュレーションとオペランドに探しを表しますことを覚えておいてください。第5章で説明したように、仕様では、スタックフレームにダブルワードを入力しますどのくらいの種類と配置を決定するために任意の特定の方法を指定しません。

 

おすすめ

転載: www.cnblogs.com/mongotea/p/11980063.html