概要
前にちょっと触れたILコードについて少しメモってた下書きを解放します。
なのであまり詳細にはまとまってません。完全にメモ。
また触れることがあったら追記するかも。
参考: ILを使った動的なコード生成入門(高速リフレクション-インスタンス生成編)
IL逆アセンブラー
.NET Compilerを手に入れる
NuGetを手に入れる
スタートメニューの検索で「dev」と打ち込むと「Developer Command Prompt for VS2015」みたいな感じで、開発者用のコマンドプロンプトが立ち上がります。
命令の種類
数値の指定
ldcから始まる命令を利用する。また、それに続けて型を指定する。
型 | 命令 | 備考 |
---|---|---|
Int32 | ldc.i4 | 32bit整数 |
Int64 | ldc.i8 | 64bit整数 |
Float32 | ldc.r4 | 32bit浮動小数点 |
Float64 | ldc.r8 | 64bit浮動小数点 |
なお、-1〜8
までは定数としてのオペコードが用意されている。
定数 | オペコード |
---|---|
-1 | ldc.i4.m1 |
0 | ldc.i4.0 |
1 | ldc.i4.1 |
2 | ldc.i4.2 |
3 | ldc.i4.3 |
4 | ldc.i4.4 |
5 | ldc.i4.5 |
6 | ldc.i4.6 |
7 | ldc.i4.7 |
8 | ldc.i4.8 |
ジャンプ命令
無条件ジャンプはbr
命令を使う
br target
target
には通常、メソッド内のオフセット位置を4バイト整数で指定するが、ラベルを指定して実行することもできる。
ラベルの指定は以下のようにする。
id:
ラベルを記載した次の行がターゲットとなる。
.assembly extern mscorlib { }
.assembly test { }
.method static void Main() cil managed
{
.entrypoint
ldstr "最初のメッセージ"
call void [mscorlib]System.Console::WriteLine(string)
br target
ldstr "スキップされるメッセージ"
call void [mscorlib]System.Console::WriteLine(string)
target:
ldstr "ターゲットメッセージ"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
分岐命令
分岐条件には、メソッド呼び出しなどと同様にスタックに積まれた値を元に判断されます。
分岐には、値が0
以外の場合に実行されるbrtrue
命令と、0
またはnull
の場合に実行されるbrfalse
命令があります。
書式はbr
命令と同様になります。
brtrue target
この命令を実行するとスタックに積まれている値をポップしそれを評価します。