http://www.developer.com/net/csharp/article.php/2106031/NET-Under-the-Hood-a-Little-ILDASM.htm
From Kate Gregory's Codeguru column, "Using Visual C++ .NET". One of the really exciting things about working with .NET is the idea of a ".NET language"—a language that emits managed code and conforms to the Common Language Specification. And (at least in theory, anyway) if you write code in two or more of these languages, they will compile to the same intermediate language, or IL. So, is C++ part of the in-crowd? Does a simple C++ application compile to the same IL as the equivalent Vb or C# application? Let's see. Here's a little C++ console application: Here's the equivalent in C#: And the same thing in VB: It's an interesting aside to see how names are assigned. I created a blank solution and added projects to it: All of these console applications do the same thing: print the numbers 0 to 9, one per line, on the console. ILDASM is the Intermediate Language Disassembler. If you use a "Visual Studio. NET Command Prompt" (Start, Programs, Visual Studio .NET, Visual Studio .NET Tools, Visual Studio .NET Command Prompt), the environment variables will be set properly to enable you to use ILDASM and other handy utilities. From this command prompt, you can cd to the folder with an exe or dll file (a managed one, with IL in it) and take a look at the IL, like this: The first screen shows the namespaces, classes, and modules in the assembly, along with the functions in each class or module. Here's SimpleC++ in ILDASM: The small yellow S in the pink square next to main and _mainCRTStartup indicate that they are static functions. Double-clicking the main expands the IL for the function. Here it is: Now, this may look intimidating, but actually IL is human-readable. It helps if you've ever worked with assembly language, but even if you haven't, you can read this. There's a tutorial in the online help in Visual Studio that explains, for example, that ldc.i4.0 loads a four-byte zero onto the stack and stloc.0 stores the current stack value in local variable 0. It's called ILDASM Tutorial and should be easily reachable from the help index. Here's the IL generated from the C#: This is shorter, for one thing, and it doesn't have the boxing. The for loop works differently too: The C++ checks whether i is greater than or equal to 10 and, if so, jumps past the whole loop using bge. The C# initializes i to zero, then jumps to the bottom of the loop, which checks to see whether i is less than 10 and, if so, jumps back to the top of the loop using blt. Neither of these approaches is necessarily better, but it's interesting that two superficially similar languages produce such different IL for such a simple example. What about VB? Well, here's the IL generated from the VB code: This code is strangely full of nop—no operation—statements, but you can see that it is very similar to the C# code. It uses ble instead of blt because VB loops continue when the index is equal to the limit—less than or equal to—but the C# code used a less-than in the limit test. (If you mess around with the loop limits, going from 10 to 9 or from 3 to 9, for example, you'll see code that looks even more like the C# code.) What's the difference between C# and C++? They both have semicolons and brace brackets, after all. Well, that may be so, but they're very different languages. C# is far more like VB than it is like C++. And, taking a look under the hood at the IL you get from simple little applications is a good way to reveal that. What's more, because it's the IL that actually executes, any talk of faster or slower execution times needs to be underpinned with an understanding of the IL that is generated. ILDASM is a good way for you to understand what your code actually produces. Play a little! Kate Gregory is a founding partner of Gregory Consulting Limited (www.gregcons.com). In January 2002, she was appointed MSDN Regional Director for Toronto, Canada. Her experience with C++ stretches back to before Visual C++ existed. She is a well-known speaker and lecturer at colleges and Microsoft events on subjects such as .NET, Visual Studio, XML, UML, C++, Java, and the Internet. Kate and her colleagues at Gregory Consulting specialize in combining software develoment with Web site development to create active sites. They build quality custom and off-the-shelf software components for Web pages and other applications. Kate is the author of numerous books for Que, including Special Edition Using Visual C++ .NET. # # #
.NET Under the Hood: a Little ILDASM
March 6, 2003
Three Little Apps...
int _tmain(void)
{
System::Int32 i;
for (i=0; i<10; i++)
{
Console::WriteLine(__box(i));
}
return 0;
}
static void Main(string[] args)
{
System.Int32 i;
for (i=0;i<10;i++)
{
Console.WriteLine(i);
}
}
Sub Main()
Dim i As System.Int32
For i = 0 To 9
Console.WriteLine(i)
Next
End Sub
ILDASM
ildasm simplec++.exe

Click here for a larger image.
.method public static int32
modopt([mscorlib]System.Runtime.CompilerServices
.CallConvCdecl) main() cil managed
{
.vtentry 1 : 1
// Code size 36 (0x24)
.maxstack 2
.locals ([0] int32 i)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_0008
IL_0004: ldloc.0
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: ldc.i4.s 10
IL_000b: bge.s IL_0020
IL_000d: ldloca.s i
IL_000f: ldobj [mscorlib]System.Int32
IL_0014: box [mscorlib]System.Int32
IL_0019: call void [mscorlib]System.Console::
WriteLine(object)
IL_001e: br.s IL_0004
IL_0020: ldc.i4.0
IL_0021: br.s IL_0023
IL_0023: ret
} // end of method 'Global Functions'::main
.method private hidebysig static void Main(string[] args)
cil managed
{
.entrypoint
.custom instance void [mscorlib]System.
STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 20 (0x14)
.maxstack 2
.locals init ([0] int32 i)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_000e
IL_0004: ldloc.0
IL_0005: call void [mscorlib]System.Console::
WriteLine(int32)
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: add
IL_000d: stloc.0
IL_000e: ldloc.0
IL_000f: ldc.i4.s 10
IL_0011: blt.s IL_0004
IL_0013: ret
} // end of method Class1::Main
.method public static void Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute:: _
.ctor() = ( 01 00 00 00 )
// Code size 22 (0x16)
.maxstack 2
.locals init ([0] int32 i)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: call void [mscorlib]System.Console:: _
WriteLine(int32)
IL_0009: nop
IL_000a: nop
IL_000b: ldloc.0
IL_000c: ldc.i4.1
IL_000d: add.ovf
IL_000e: stloc.0
IL_000f: ldloc.0
IL_0010: ldc.i4.s 9
IL_0012: ble.s IL_0003
IL_0014: nop
IL_0015: ret
} // end of method Module1::Main
The Bottom Line
About the Author