2012-10-17 18 views
5

Mam tę sekwencję kodów CIL, którą wstrzyknięto za pomocą Mono.Cecil. Jednak zmodyfikowana aplikacja .NET C# nie będzie działać..NET CIL manipulacja stosem ewaluacji

Cel: ręcznie załadować i pop wartości ze stosu do wyświetlania w Console.WriteLine

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

To proste main() Program I modyfikowany:

.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 
} 

jednak powyższego kodu nie można uruchomić. Próbowałem zmienić blt.s na clt i , ale to też nie działa. Czy ktoś wie, czy możliwe jest osiągnięcie mojego celu? Dzięki.

EDYCJA: Według ECMA-335, III.1.7.5, może istnieć ograniczenie do gałęzi wstecz. Nie jestem pewien, czy tak jest.

W szczególności, jeśli analiza single-pass przybywa instrukcją, nazywają to miejsce X, że natychmiast następuje bezwarunkowe gałąź, i gdzie X nie jest celem wcześniejszego nauczania oddział , to państwo stosu ewaluacji w X, wyraźnie, nie można wyprowadzić z istniejących informacji . W tym przypadku CLI wymaga, aby stos oceny w X był pusty.

+3

Jaki jest faktyczny błąd podczas uruchamiania programu? Czy próbowałeś już uruchomić peverify w zmodyfikowanym programie? – Jeff

+2

Dajesz * weryfikator * zbyt wiele trudu, aby sprawdzić, czy stos jest zrównoważony. Musiałby wystarczająco zagłębić się w kod, aby przeanalizować, jak często działa pętla. Nie robi tego. –

Odpowiedz

2

Kod IL wygląda dobrze, ale myślę, że CLR może nie być w stanie sprawdzić, czy stos jest uszkodzony po zakończeniu tej metody. Kiedy coś zostanie pchnięte na stos, CLR sprawdza, czy wartość jest również wyskakiwana ze stosu.

Więc jeśli wypchniesz 3 wartości na stos, CLR może nie być w stanie sprawdzić, czy twoja pętla działa trzy razy, więc CLR nie wie, czy nadal istnieją wartości na stosie, gdy metoda powraca.

+0

Podejrzewałem, że tak jest, ponieważ stos jest niestabilny w ramach procedury i musi zostać opróżniony przed "wywołaniem". był zbytnio przyzwyczajony do elastyczności zapewnionej w montażu binarnym. – Ron