[ad_1]
class Program { static void Main(string[] args) { int first = 10; int second = 20; int third = 30; int forth = 40; int fifth = 50; } }
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 18 (0x12) .maxstack 1 .locals init ([0] int32 first, [1] int32 second, [2] int32 third, [3] int32 forth, [4] int32 fifth) IL_0000: nop IL_0001: ldc.i4.s 10 IL_0003: stloc.0 IL_0004: ldc.i4.s 20 IL_0006: stloc.1 IL_0007: ldc.i4.s 30 IL_0009: stloc.2 IL_000a: ldc.i4.s 40 IL_000c: stloc.3 IL_000d: ldc.i4.s 50 IL_000f: stloc.s fifth IL_0011: ret } // end of method Program::Main
私の質問は次のとおりです。
1 番目、2 番目、3 番目、4 番目、5 番目の変数は、スタック上のローカル変数として割り当てられます
スタック上の 5 つの変数の場合、.maxstack は 5 である必要があると思います
しかし、.maxstackは1を示しています その意味?
解決策 1
これを調べなければならなかったのですが、正確に0行のILを書きましたが、あなたの質問は興味深いです:
.maxstack は 最大評価スタックの深さ/高さ、IL を通過すると、評価スタックには最大で 1 つしかありません。
.locals init ([0] int32 first, [1] int32 second, [2] int32 third, [3] int32 forth, [4] int32 fifth)
ローカル変数を宣言します。
IL_0000: nop
無操作?? -何もしないのに、なぜわざわざ? 私が言うように、私はこのことの専門家ではありません。
IL_0001: ldc.i4.s 10
定数 10 を評価スタックにロードします (スタック サイズ = 1)。
IL_0003: stloc.0
値を評価スタックからローカルにポップします[0]. 評価スタック サイズ = 0。 他の変数についてすすぎ、繰り返しますが、最大評価スタック サイズ 5 つの値のそれぞれがスタックにプッシュされ、変数に個別にポップされるため、1 のままです。
仮説的に次のように書き直すことができると思います(おそらくコンパイルされません):
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 18 (0x12) .maxstack 5 .locals init ([0] int32 first, [1] int32 second, [2] int32 third, [3] int32 forth, [4] int32 fifth) IL_0000: nop IL_0001: ldc.i4.s 10 IL_0003: ldc.i4.s 20 IL_0004: ldc.i4.s 30 IL_0006: ldc.i4.s 40 IL_0007: ldc.i4.s 50 //Stack size 5 IL_0009: stloc.4 //Stack size 4 IL_000a: stloc.3 //Stack size 3 IL_000c: stloc.2 //Stack size 2 IL_000d: stloc.1 //Stack size 1 IL_000f: stloc.0 //Stack size 0 IL_0011: ret }
[Edit]
これは yuthub のコメントへの返信です。MSIL/CIL は私のコンフォート ゾーンをはるかに超えているという警告とともに読む必要があります。:
実行時に複数のスタックが動作しています。 const が ldc によってプッシュされると、 評価 スタック (参照 ここ[^] 良い記事のために)。 値が評価スタックからポップされると、この場合はメソッド内の int 宣言であり、別のスタックに配置されます。スタックは、スタックとヒープについて議論するときに通常「スタック」として議論するスタックです。たとえば、C#のメモリ。 明確にするために、質問の前半を更新しました。
解決策 2
ここでの返信が非常に遅くなりましたが、それは、グーグルでこの記事を見つけた人に役立つ情報を追加したいからです.
.maxstack は、評価スタックではなくメソッド スタックの一部である .locals とはまったく関係ありません。
私たちが見ているのは、デバッグ構成で構築されたものを逆アセンブルした結果です。
これが、.locals リスト内のすべてのローカル変数に名前が付けられている理由であり、また、 いいえ オペレーション。 実際には操作はありませんが、ブレークポイントを配置できるコード内の関連するポイントをデバッガーに与えるために、プログラム内の実際のステップのようなものです。
リリース構成は、パフォーマンスのために最適化されたはるかに短いコードを生成します。これらの nop 命令は含まれておらず、ローカルの名前も削除されています。
ただし、実行時に実行される次のコンパイルステップである JIT によって、実際にはさらに多くの最適化が行われることに注意してください。
[ad_2]
Source link
コメント