IL を少し調べ始めたところですが、コンパイラの出力から余分なコードを削除する試み (以下を参照) に意図しない副作用があったかどうかに興味があります。
結果に関するいくつかの質問:
- オリジナルの nop 操作の目的は何ですか?
- 元のメソッドの最後の br.s の目的は何ですか?
- 書き直されたバージョンは何らかの点で不適切ですか?
元の C# コード:
class Program {
public static int Main() {
return Add(1, 2);
}
public static int Add(int a, int b) {
return a + b;
}
}
(オリジナル)でコンパイルcsc.exe
および逆アセンブル:ildasm.exe
.method public hidebysig static int32 Main() cil managed
{
.entrypoint
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: ldc.i4.2
IL_0003: call int32 Program::Add(int32, int32)
IL_0008: stloc.0
IL_0009: br.s IL_000b
IL_000b: ldloc.0
IL_000c: ret
}
.method public hidebysig static int32 Add(int32 a,
int32 b) cil managed
{
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL_0008: ret
}
書き直しました(同一の出力を生成します):
.method public hidebysig static int32 Main() cil managed
{
.entrypoint
.maxstack 2
ldc.i4.1
ldc.i4.2
call int32 Program::Add(int32, int32)
ret
}
.method public hidebysig static int32 Add(int32 a, int32 b) cil managed
{
.maxstack 2
ldarg.0
ldarg.1
add
ret
}