2

C# から IL (CIL/MSIL など) にコードを変換しています。次の利用可能な空き場所に保存できるようにしたいので、条件付きで立ち往生しています。例:

var x = 0;
if(x > 20)
 x = 1;

Console.WriteLine(x);

これを正しい IL と思われるものに変換すると、次のようになります。

IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  ldloc.0     
IL_0004:  ldc.i4.s    14 
IL_0006:  cgt         
IL_0008:  ldc.i4.0    
IL_0009:  ceq         
IL_000B:  stloc.1     
IL_000C:  ldloc.1     
IL_000D:  brtrue.s    IL_0011
IL_000F:  ldc.i4.1    
IL_0010:  stloc.0     
IL_0011:  ldloc.0     
IL_0012:  call        System.Console.WriteLine

これは正しい IL だと思いますが、私の例は非常に静的です。IL コードで見ると、ceq の結果が loc.1 に格納されます。

したがって、私の問題です-コンパイラは、loc.0がすでに取得されていることを確認し(変数「x」)、次の空き場所である1を使用しました。私の目標は、特定のメソッドがN変数を持つことができる場所でこれを動的に行うことです条件の前。

最後に、ここに私の質問があります。C# から、"stloc. nextAvailable " と言うオペコードを発行するにはどうすればよいですか? それは同等の負荷ですか?

4

2 に答える 2

3

stlocldloc定数インデックスでのみ機能します。ただし、これは悪いことではありません。他のコードを発行した場合、次の利用可能なインデックスが既にあることを意味します。または、何らかの方法でコードを別の場所で取得した場合は、すべてのローカル インデックスの最大値を取得して 1 つ追加するだけです (または、メソッドヘッダーからローカルの数を読み取ります (ある場合)。

または、ローカルをスキップして結果をcgt直接brfalse使用するか ( を使用)、ble命令を使用することもできます。すると、この問題はそもそも現れません。

于 2012-06-20T00:20:58.307 に答える
2

私には、デバッグ モード用にコンパイル中に生成された IL を見ているように見えます。stloc.1ldloc.1は、コードに存在しないローカルを参照していますが、大なり記号の上にカーソルを置いているときに素敵な小さなツールチップを表示するために作成される可能性があります。デバッグ。

リリース モードで生成された IL は、次のようになると思います (Console.WriteLine(0);事前に全体を最適化しない場合)。

//load the 4-byte integer 0 on to the stack
IL_0001:    ldc.i4.0
//set the value of local 0 (x) to the previous value on the stack (0)
IL_0002:    stloc.0
//load up x for the comparison
IL_0003:    ldloc.0
//load the 4-byte integer 0x14 (20) on to the stack
IL_0004:    ldc.i4.s    14
//check to see whether two elements back on the stack is greater than one element back on the stack (x > 20), push 1 one back on the stack in the case the first is greater, 0 otherwise
IL_0005:    cgt
//if 0x14 (20) was the greater (or equal) value, jump over the body of the if block
IL_0006:    brfalse.s    IL_0009
//load the 4-byte integer 1 (1) on to the stack
IL_0007:    ldc.i4.1
//set the value of local 0 (x) to the previous value on the stack (1)
IL_0008:    stloc.0
//load the value of local 0 (x) on to the stack
IL_0009:    ldloc.0
//call Console.WriteLine
IL_000A:    call    System.Console.WriteLine
于 2012-06-20T08:55:46.813 に答える