我能正确理解这个MSIL代码吗?

时间:2012-08-29 10:09:02

标签: c# .net cil il ilasm

我在C#中有以下代码

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

而且我正在阅读IL代码,我之前从未编写过程序集,所以我问的是我的每行代码是否正确。

.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

我能正确理解这个程序吗?

3 个答案:

答案 0 :(得分:11)

差不多;我唯一澄清的是框(IL_0006和IL_0011)是类型特定的,因此它显式构建了一个int类型的框(它不仅仅是“最后一个值类型” “)。

此外,“空评估堆栈”具有误导性;这不太对 - 例如,call消耗给定数量的职位 - 它不会“清空”它。 永远不会一个“空评估堆栈”语义 - 它总是“消耗许多值,放回一些值”(其中任何一个都可能为零)。

答案 1 :(得分:3)

是的,您的理解几乎完全正确。一件事:IL_0010不从堆栈加载,它从本地加载。 (本地最终在运行时堆栈上,但在IL级别,这些称为本地)。

答案 2 :(得分:2)

这是正确的,虽然我会用一些不明确的措辞来争论,例如:

  

将评估堆栈位置0放入堆栈位置0,评估堆栈清空

我会说

  

将堆栈顶部的第0个条目放入堆栈变量0th,然后弹出

仅仅是因为我认为在大多数情况下,“不太正式”的措辞只是更清楚地阅读,但是,似乎还不错。

编辑:嗯...在事后的想法中,我会说没有“堆栈”和“评估堆栈”之类的两件事。只有“堆栈”。堆栈可见部分开始的标记部分,具有局部变量的部分可称为“槽”。我想用IL,你可以说“局部变量Nth”,一切都很清楚,但我认为几个不同的变量可能会映射到同一个槽,所以它可能会引起一些混乱。此外,当您使用堆栈时,没有像“清空”这样的操作。仅推送/弹出具有明确指定数量的条目才能被复制。