23

これらのILは私がもっと見るものをコード化するので、それらを正しく解釈する方法を学びたいと思います。

C#コンパイラやその他のドキュメントが見つからなかったので、この一般的なドキュメントを学んだ後は、残りの部分はほとんど処理できると思います。

以下は私が知る必要があることを含むいくつかのサンプルILコードです:

サンプル1:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       15 (0xf)
  .maxstack  1
  .locals init ([0] class EnumReflection.DerivedClass derivedClass)
  IL_0000:  nop
  IL_0001:  newobj     instance void EnumReflection.DerivedClass::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  callvirt   instance void EnumReflection.DerivedClass::WriteOutput()
  IL_000d:  nop
  IL_000e:  ret
} // end of method Program::Main

サンプル2:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       38 (0x26)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldstr      "Hello"
  IL_0006:  stfld      string EnumReflection.DerivedClass::hello
  IL_000b:  ldarg.0
  IL_000c:  ldstr      "World"
  IL_0011:  stfld      string EnumReflection.DerivedClass::world
  IL_0016:  ldarg.0
  IL_0017:  ldc.i4.s   123
  IL_0019:  stfld      int32 EnumReflection.DerivedClass::age
  IL_001e:  ldarg.0
  IL_001f:  call       instance void EnumReflection.BaseClass::.ctor()
  IL_0024:  nop
  IL_0025:  ret
} // end of method DerivedClass::.ctor

私はこれらのコードを作成してから何をするかを知っています:-)しかし、対応するILコードについてもっと知りたいです。

これらのサンプルには、のようなILコードが含まれていますが、コマンドを疑問符で説明していただけますか?また、それらのコマンドは何を表していますか?簡単に覚えることができます。

  • nop(デバッグ用-操作なし)
  • newobj(ヒープ内に新しいオブジェクトを作成しているようです)
  • stloc.0?
  • ldloc.0?
  • ret?
  • ldarg.0?
  • ldstr?
  • stfld?
  • ldc.i4.s?
  • .ctor-コンストラクター

ILを理解することは、特定のコンパイラがコードを生成し、特定の場合にどのように動作するかを明らかにするために重要です。

ただし、ILに関する例も含まれている優れたドキュメントは見つかりませんでした。C#3.0を使用したCLRは優れた本ですが、最終的にはILの本ではないため、ILについてすべてを説明しているわけではありません。

編集:

私はスペックを見つけました、そして彼らはこれらを伝えます: @usrに感謝します。

  • nop(デバッグ用-操作なし)
  • newobj-新しいオブジェクトを作成します
  • stloc.0-スタックからローカル変数へのポップ値
  • ldloc.0?-ローカル変数をスタックにロードします
  • ret-メソッドから戻る
  • ldarg.0-引数0をスタックにロードします。
  • ldstr-リテラル文字列をロードします
  • stfld-オブジェクトのフィールドに格納します
  • ldc.i4.s-numをint32、短縮形としてスタックにプッシュします。
  • .ctor-コンストラクター
4

4 に答える 4

12

ILをカバーしている本がいくつかあります。

また、リバースエンジニアリングに関する本の中にはILに関するセクションがあるものもあります。

参照:

于 2012-04-21T15:37:07.153 に答える
10

MicrosoftはCLRを標準化し、それらの標準を公開しました。パーティションIIIには、IL / CILに関する豊富な情報が含まれており、学習に適しています。優れたドキュメントです。

例によってILを学ぶこともできます。C#でいくつかの簡単なメソッドをコンパイルし、リフレクターでILを確認します(ILモードがあります)。

于 2012-04-21T15:27:21.063 に答える
9
  • nop-no-op
  • newobj-オブジェクトを作成し、そのコンストラクターを呼び出します。
  • stloc.0-スタックから値をポップし、それを最初のローカル変数に格納します
  • ldloc.0-最初のローカル変数をスタックにプッシュします
  • ret-戻る
  • ldarg.0-最初の引数(thisインスタンスメソッド内)をスタックにプッシュします
  • ldstr-文字列をスタックにプッシュします
  • stfld-スタック上のデータを使用してフィールドを設定します。
  • ldc.i4.s-指定された数値をintとしてプッシュします。
  • .ctor-コンストラクター

これらのオペコードに関する優れたドキュメントのソースを見つけることをお勧めします(ただし、ウィキペディアが最適な場合があります:()。System.Reflection.Emitのドキュメントには、オペコードに関するかなり詳細なドキュメントがあります。

そして何よりも、小さなプログラムを作成し、IL出力を調べます。それが学ぶための最良の方法です。

于 2012-04-21T15:41:41.563 に答える
8

各オペコードの簡単な概要が必要な場合は、System.Reflection.Emit名前空間を検査するよりも悪い結果になる可能性があります。

たとえば、OpCodesオペコードごとに静的フィールドを持つクラスがあります。次に、これらのそれぞれについて、スタックの動作の観点からさらに詳しく説明します。例Ldarg_0

ldarg.0命令は、0でインデックス付けされた引数を評価スタックにプッシュします。ldarg.0命令を使用して、値型またはプリミティブ値を着信引数からコピーすることにより、スタックにロードできます

于 2012-04-21T15:33:27.527 に答える