6

ILGenerator を使用していくつかの IL を生成しています。ここに私のコードがあります。

DynamicMethod method = new DynamicMethod("test", null, Type.EmptyTypes);
ILGenerator gen = method.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Ldc_I4_S, 100);

これにより、次の IL が生成されました。

IL_0000:  ldarg.0    
IL_0001:  ldarg.1    
IL_0002:  ldc.i4.s   100
IL_0004:  nop        
IL_0005:  nop        
IL_0006:  nop        

(ILStream という名前の VS Virtulizer から IL コードを取得します)

nops はどこからコーディングしますか? それらを取り除く方法はありますか?私はいくつかの C# コードを模倣しようとしていますが、3 つの nop がありません。

4

2 に答える 2

8

あなたは「nop」を取り除くのに正しい方向にいます:

Emit 呼び出しに追加の引数を指定する場合は、必ず MSDN で適切な引数の型を確認してください。

OpCodes.Ldc_I4_S について、MSDN は次のように述べています。

ldc.i4.s は、-128 から 127 までの整数を >evaluation スタックにプッシュするためのより効率的なエンコーディングです。

次の Emit メソッドのオーバーロードでは、ldc.i4.s オペコードを使用できます。

ILGenerator.Emit(OpCode, バイト)

したがって、スタックに「int8」をロードしようとしているが、「int32」または「short」値を提供しようとしているため、コードの 2 番目の部分は実行時に (厄介な nop 以外に) 予測できない結果をもたらします。

else if (IsBetween(value, short.MinValue, short.MaxValue))
{
    gen.Emit(OpCodes.Ldc_I4_S, (short)value);
}
else
{
    gen.Emit(OpCodes.Ldc_I4_S, value);
}

int32/short (またはバイトより大きいもの) をスタックに適切にロードする場合は、Ldc_I4_S の代わりに Ldc_I4 を使用する必要があります。したがって、コードは上記のサンプルではなく次のようになります。

else
{
    gen.Emit(OpCodes.Ldc_I4, value);
}

これは大雑把な推測ですが、生成された 3 つの nop はおそらく int32 からの余分なバイトと関係があります。

それが役立つことを願っています...

于 2011-11-15T09:23:52.187 に答える
3

int を値にキャストすることで問題を解決しました。

コード:

private static bool IsBetween(int value, int min, int max)
{
    return (value >= min && value <= max);
}

private static void WriteInt(ILGenerator gen, int value)
{
    gen.Emit(OpCodes.Ldarg_1);
    if (IsBetween(value, sbyte.MinValue, sbyte.MaxValue))
    {
        gen.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
    }
    else if (IsBetween(value, byte.MinValue, byte.MaxValue))
    {
        gen.Emit(OpCodes.Ldc_I4_S, (byte)value);
    }
    else if (IsBetween(value, short.MinValue, short.MaxValue))
    {
        gen.Emit(OpCodes.Ldc_I4_S, (short)value);
    }
    else
    {
        gen.Emit(OpCodes.Ldc_I4_S, value);
    }
}
于 2009-09-30T15:01:30.500 に答える