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: ble.s IL_0004
IL_0013: ret
} // end of method App::Main
Listing 12.1 (continued)
Listing 12.1 starts with a few basic definitions regarding the method listed.
The method is specified as .entrypoint, which means that it is the first code
executed when the program is launched. The .maxstackstatement specifies
the maximum number of items that this routine loads into the evaluation
stack. Note that the specific item size is not important here—don’t assume 32
bits or anything of the sort; it is the number of individual items, regardless of
their size. The following line defines the method’s local variables. This func-
tion only has a single int32local variable, named V_0. Variable names are
one thing that is usually eliminated by the compiler (depending on the specific
compiler).
The routine starts with the ldcinstruction, which loads the constant 1 onto
the evaluation stack. The next instruction, stloc.0, pops the value from the
top of the stack into local variable number 0 (called V_0), which is the first
(and only) local variable in the program. So, we’ve effectively just loaded the
value 1 into our local variable V_0. Notice how this sequence is even longer
than it would have been in native IA-32 code; we need two instructions to load
a constant into local variable. The CLR is a stack machine—everything goes
through the evaluation stack.
The procedure proceeds to jump unconditionally to address IL_000e. The
target instruction is specified using a relative address from the end of the cur-
rent one. The specific branch instruction used here is br.s, which is the short
version, meaning that the relative address is specified using a single byte. If
the distance between the current instruction and the target instruction was
larger than 255 bytes, the compiler would have used the regular brinstruc-
tion, which uses an int32to specify the relative jump address. This short
form is employed to make the code as compact as possible.
434 Chapter 12