2012-10-17 12 views
5

Mono.Cecilを使用して注入したCILコードのシーケンスがあります。ただし、変更された.NET C#アプリケーションは実行されません。.NET CILによる評価スタックの操作

目的:、ただし

.method private hidebysig static void Main(string[] args) cil managed 
{ 

    .entrypoint 
    .maxstack 5 
    .locals init (
     [0] int32 num, 
     [1] int32 num2) 
    L_0000: ldc.i4.6 //manually push value 6 to stack 
    L_0001: ldc.i4.5 //manually push value 5 to stack 
    L_0002: ldc.i4.4 //manually push value 4 to stack 
    L_0003: ldc.i4.0 //push int i initial value 0 to stack 
    L_0004: stloc.0 //pop and store to int i variable to variable num 
    L_0005: br.s L_0013 
    L_0007: nop 
    L_0008: stloc.1 //pop the pushed values 6,5 and 4 to variable num2 
    L_0009: ldloc.1 //load value of num2 to stack 
    L_000a: call void [mscorlib]System.Console::WriteLine(int32) //pop value of num2 and print 
    L_000f: ldloc.0 //load previous value in variable num to stack 
    L_0010: ldc.i4.1 //load incremental value 1 to stack 
    L_0011: add //pop and add the top 2 values, result is pushed to stack 
    L_0012: stloc.0 //store the new result to variable num. (int i) 
    L_0013: ldloc.0 //push int i variable value to stack 
    L_0014: ldc.i4.3 //push value 3 to stack as number of times to loop 
    L_0015: blt.s L_0007 //branch less than (pop and cmp the top 2 values in stack) 
    L_0017: ret 
} 

: 手動負荷とポップ値スタックからConsole.WriteLine

for (int i = 0; i < 3; i++) 
     { 
      int z = some value popped manually from stack;     
      Console.WriteLine(z); 
     } 

に表示するには、これは私が修正さ単純メイン()プログラムです。上記のコードは実行できません。 blt.scltbr_true.sに変更しようとしましたが、どちらも動作しません。私の目的を達成することが可能かどうかを知っていますか?ありがとう。

EDIT: ECMA-335、III.1.7.5によると、後方分岐制約が存在する可能性があります。これが当てはまるかどうかはわかりません。特に

その単一パス分析は、命令に到達した場合、 は直ちに無条件分岐をたどること、位置Xを呼び出し、そしてXは、以前分岐 命令、状態の対象ではありません評価スタックのXで、明らかに、既存の 情報から派生することはできません。この場合、CLIは、Xの評価スタックが空であることを要求します。

+3

プログラムを実行する実際のエラーは何ですか?修正プログラムでpeverifyを実行しようとしましたか? – Jeff

+2

ベリファイアには、スタックがバランスをとっているかどうかを確認するのに苦労しすぎます。ループがどのくらいの頻度で実行されているかを分析するには、コードを十分に深く見なければなりません。それはしません。 –

答えて

2

IL-Codeは大丈夫ですが、メソッドの完了後にスタックが破損しているかどうかをCLRが確認できない可能性があります。何かがスタックにプッシュされると、CLRは値がスタックからポップされているかどうかをチェックします。

したがって、3つの値をスタックにプッシュすると、ループが3回実行されているかどうかをCLRが確認できない場合があります。そのため、メソッドが復帰してもスタックに値がまだ残っているかどうかはわかりません。

+0

私はスタックがプロシージャ内で揮発性であり、 'コール'の前に空にされなければならないと考えています。バイナリアセンブリで提供される柔軟性にもあまりにも慣れていました。 – Ron

関連する問題