Free mag vol1 | Page 712

CHAPTER 18  UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES  Note Recall that CIL is not directly executed, but compiled on demand. During the compilation of CIL code, many of these implementation redundancies are optimized away. Furthermore, if you enable the code optimization option for your current project (using the Build tab of the Visual Studio Project Properties window), the compiler will also remove various CIL redundancies. To understand how CIL leverages a stack-based processing model, consider a simple C# method, PrintMessage(), which takes no arguments and returns void. Within the implementation of this method, you will simply print out the value of a local string variable to the standard output stream, like so: public void PrintMessage() { string myMessage = "Hello."; Console.WriteLine(myMessage); } If you were to examine how the C# compiler translates this method in terms of CIL, you would first find that the PrintMessage() method defines a storage slot for a local variable using the .locals directive. The local string is then loaded and stored in this local variable using the ldstr (load string) and stloc.0 opcodes (which can be read as “store the current value in a local variable at storage slot zero”). The value (again, at index 0) is then loaded into memory using the ldloc.0 (“load the local argument at index 0”) opcode for use by the System.Console.WriteLine() method invocation (specified using the call opcode). Finally, the function returns via the ret opcode. Here is the (annotated) CIL code for the PrintMessage() method (note that I’ve removed the nop opcodes from this listing, for brevity): .method public hidebysig instance void PrintMessage() cil managed { .maxstack 1 // Define a local string variable (at index 0). .locals init ([0] string myMessage) // Load a string onto the stack with the value "Hello." ldstr " Hello." // Store string value on the stack in the local variable. stloc.0 // Load the value at index 0. ldloc.0 // Call method with current value. call void [mscorlib]System.Console::WriteLine(string) ret } 655