2012-10-17 27 views
5

Tôi có chuỗi mã CIL này mà tôi đã tiêm thông qua việc sử dụng Mono.Cecil. Tuy nhiên, ứng dụng .NET C# đã sửa đổi sẽ không chạy.Thao tác .NET CIL của ngăn xếp đánh giá

Mục tiêu: thủ tải và pop giá trị từ ngăn xếp để hiển thị trong Console.WriteLine

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

Đây là chương trình đơn giản main() tôi sửa đổi:

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

Tuy nhiên, mã trên không thể chạy. Tôi đã thử thay đổi blt.s thành cltbr_true.s nhưng nó cũng không hoạt động. Có ai biết nếu nó có thể đạt được mục tiêu của tôi? Cảm ơn.

EDIT: Theo ECMA-335, III.1.7.5, có thể có ràng buộc nhánh ngược. Không chắc chắn nếu đây là trường hợp.

Đặc biệt, nếu đó phân tích đơn-pass đến tại một lệnh, gọi nó là vị trí X, mà ngay lập tức sau một chi nhánh không điều kiện, và trong đó X không phải là mục tiêu của một lệnh rẽ nhánh trước đó, sau đó nhà nước của ngăn xếp đánh giá tại X, rõ ràng, không thể bắt nguồn từ thông tin hiện tại . Trong trường hợp này, CLI yêu cầu ngăn xếp đánh giá tại X phải trống.

+3

Lỗi thực tế bạn đang chạy chương trình là gì? Bạn đã thử chạy peverify trên chương trình sửa đổi của bạn? – Jeff

+2

Bạn đang cung cấp cho trình xác minh * cách * quá nhiều thời gian khó khăn để kiểm tra xem ngăn xếp có được cân bằng hay không. Nó sẽ phải nhìn sâu vào mã để phân tích tần suất vòng lặp chạy. Nó không làm điều đó. –

Trả lời

2

Bạn mã IL có vẻ ổn, nhưng tôi nghĩ CLR có thể không kiểm tra xem ngăn xếp có bị hỏng sau khi phương thức hoàn tất hay không. Khi một cái gì đó được đẩy lên ngăn xếp, CLR sẽ kiểm tra xem giá trị có được xuất hiện từ ngăn xếp hay không. Vì vậy, nếu bạn đẩy 3 giá trị vào ngăn xếp thì CLR không thể kiểm tra xem vòng lặp của bạn có đang chạy ba lần hay không, vì vậy CLR không biết liệu vẫn còn giá trị trên ngăn xếp khi phương thức quay trở lại hay không. Quay lại đầu trang |

+0

tôi bị nghi ngờ như vậy kể từ khi ngăn xếp là dễ bay hơi trong một thủ tục và phải được làm trống trước khi một 'cuộc gọi'. đã quá quen với sự linh hoạt được cung cấp trong lắp ráp nhị phân. – Ron