接着要执行第十六道指令 call string [mscorlib] System.String::Concat(object, object)。此指令的意思是:从 Evaluation Stack 中取出兩個值,此二值皆為 Reference Type,下面的值当作第一個参数,上面的值当作第二個参数,呼叫 mscorlib.dll 所提供的 System.String.Concat() method 來將此二参数進行字串接合(String Concatenation),將接合出來的新字串放在 Managed Heap,將其 Reference 放進 Evaluation Stack。值得注意的是:由於 System.String.Concat() 是 static method,所以此處使用的指令是 call,而非 callvirt(呼叫虚拟)。执行完此道指令之后,记忆体的变化如图17 所示:
图17
請注意:此時 Managed Heap 中的 Int32(6) 以及 String("i+j+k=") 已經不再被參考到,所以变成垃圾,等待 GC 的回收。
接着要执行第十七道指令 call void [mscorlib] System.Console::WriteLine(string)。此指令的意思是:从 Evaluation Stack 中取出一個值,此值為 Reference Type,將此值当作参数,呼叫 mscorlib.dll 所提供的 System.Console.WriteLine() method 來將此字串显示在 Console 視窗上。System.Console.WriteLine() 也是 static method。执行完此道指令之后,记忆体的变化如图18 所示:
图18接着要执行第十八道指令 ret。此指令的意思是:結束此次呼叫(也就是 Main 的呼叫)。此時会檢查 Evaluation Stack 內剩下的資料,由於 Main() 宣告不需要传出值(void),所以 Evaluation Stack 內必須是空的,本范例符合這樣的情況,所以此時可以順利結束此次呼叫。而 Main 的呼叫一結束,程式也随之結束。执行完此道指令之后(且在程式結束前),记忆体的变化如图19 所示:
图19通过此范例,读者应该可以对于 IL 有最基本的认识。对 IL 感兴趣的读者应该自行阅读 Serge Lidin 所著的《Inside Microsoft .NET IL Assembler》(Microsoft Press 出版)。我认为:熟知 IL 每道指令的作用,是 .NET 程式員必备的知识。.NET 程式員可以不会用 IL Assembly 写程式,但是至少要看得懂 ILDASM 反编译出來的 IL 組合码。