2012-08-29 29 views
17

Tôi có đoạn mã sau trong C#Tôi có hiểu mã MSIL này chính xác không?

// test.Program 
private static void Main() 
{ 
    int x = 5; 
    int y = 100; 
    Console.WriteLine(y + ", " + x); 
} 

Và tôi đọc mã IL, tôi chưa bao giờ được lập trình lắp ráp trước vì vậy tôi hỏi nếu những gì tôi từng dòng làm là đúng.

.method private hidebysig static 
    void Main() cil managed 
{ 
    // Method begins at RVA 0x2058 
    // Code size 33 (0x21) 
    .maxstack 3 // maximum stack in this method is 3 
    .entrypoint // method is initial entry point 
    .locals init (// reserves memory for x and y variables 
     [0] int32 x, // x variable is reserved on position 0 of the stack 
     [1] int32 y // y variable is reserved on position 1 of the stack 
    ) 
    IL_0000: ldc.i4.5  // integer of 4 bytes in size and the value of 5 is loaded onto the evaluation stack position 0 
    IL_0001: stloc.0  // put evaluation stack position 0 into the stack position 0, the evaluation stack is emptied 
    IL_0002: ldc.i4.s 100 // integer of 4 bytes in size and the value of 100 is loaded onto the evaluation stack position 0 
    IL_0004: stloc.1  // put evaluation stack position 0 onto the stack position 1, the evaluation stack is emptied 
    IL_0005: ldloc.1  // load stack position 1 into the evaluation stack position 0 
    IL_0006: box [mscorlib]System.Int32 // box last valuetype placed on evaluation stack, replace valuetype with reference on evaluation stack position 0, do not empty stack 
    IL_000b: ldstr ", " // put reference to string on evaluation stack position 1 
    IL_0010: ldloc.0  // load stack position 0 into the evaluation stack position 2 
    IL_0011: box [mscorlib]System.Int32 // box last valuetype placed on evaluation stack, replace valuetype with reference on evaluation stack position 0, do not empty stack 
    IL_0016: call string [mscorlib]System.String::Concat(object, object, object) // call Concat, pass values on evaluation stack, empty evaluation stack, put result of concat on evaluationstack 
    IL_001b: call void [mscorlib]System.Console::WriteLine(string) // pass first value in evaluation stack 
    IL_0020: ret   // return 
} // end of method Program::Main 

Tôi có hiểu chương trình này chính xác không?

Trả lời

11

Khá nhiều; điều duy nhất tôi muốn làm rõ là hộp (IL_0006 và IL_0011) là loại cụ thể, do đó, rõ ràng là đang xây dựng một hộp kiểu int (nó không chỉ là "valuetype cuối cùng").

Ngoài ra, "ngăn xếp đánh giá trống" là gây hiểu nhầm; điều đó không đúng - ví dụ, call tiêu thụ một số vị trí nhất định - nó không "trống" nó. Có không bao giờ ngữ nghĩa "ngăn xếp đánh giá trống" - luôn luôn "tiêu thụ một số giá trị, đặt lại một số giá trị" (một trong hai giá trị đó có thể bằng 0).

+0

Khi n số vị trí được tiêu thụ bởi một cái gì đó (gọi ví dụ), chỉ có vị trí hàng đầu được tiêu thụ phải không? Và sau đó đặt một số giá trị trở lại trên ngăn xếp đánh giá? Tôi đoán điều này là đúng, bởi vì nó là một 'chồng' sau khi tất cả, nhưng tôi chỉ yêu cầu để chắc chắn. – ProgrammerAtWork

+1

Có. Một hoạt động giả định có thể đọc A, B, C, D và tạo ra Y, Z sẽ bật 4 mục từ ngăn xếp *, tính kết quả *, và sau đó sẽ đẩy 2 mục mới vào nó. (*) không cần thiết theo thứ tự đó, nhưng việc đẩy luôn là lần cuối cùng. – quetzalcoatl

3

Vâng, sự hiểu biết của bạn gần như hoàn toàn chính xác. Một điều: IL_0010 không tải từ ngăn xếp, nó tải từ người dân địa phương. (Người dân địa phương kết thúc trên ngăn xếp thời gian chạy nhưng ở cấp độ IL được gọi là người dân địa phương).

+0

OP mô tả "ngăn xếp đánh giá" riêng cho người dân địa phương trên ngăn xếp, nhưng tôi đồng ý sẽ tốt hơn nếu chỉ gọi họ là người dân địa phương. –

2

Nó là đúng, mặc dù tôi muốn tranh luận một chút với một số từ ngữ không rõ ràng, ví dụ:

đánh giá đặt ngăn xếp vị trí 0 vào ngăn xếp vị trí 0, chồng đánh giá là làm trống

tôi muốn nói

đưa entry 0 từ phía trên cùng của ngăn xếp vào ngăn xếp biến 0, sau đó bật

chỉ vì tôi nghĩ rằng một từ ngữ 'ít chính thức' là trong hầu hết các lần chỉ đơn giản là rõ ràng hơn để đọc, nhưng othwerwise, có vẻ như OK.

chỉnh sửa: hm .. trong một suy nghĩ, tôi muốn nói rằng không có hai thứ như "ngăn xếp" và "ngăn xếp đánh giá". Chỉ có "ngăn xếp". Phần được đánh dấu của phần bắt đầu của phần hiển thị của ngăn xếp, phần có các biến cục bộ có thể được gọi là "vị trí". Tôi giả sử rằng với IL, bạn chỉ có thể nói "biến cục bộ Nth" và mọi thứ thường rõ ràng, nhưng tôi nghĩ rằng một số biến khác nhau có thể được ánh xạ tới cùng một vị trí, do đó có thể gây nhầm lẫn. Ngoài ra, không có hoạt động như "đổ" khi bạn làm việc với ngăn xếp. Chỉ đẩy/bật với số lượng mục được chỉ định rõ ràng được sao chép.

Các vấn đề liên quan