Skip to content

Instantly share code, notes, and snippets.

int i = 128;
// Push the value 128 (0x00000080) onto the stack
IL_0001: ldc.i4 80 00 00 00
// Store our 128 at location 0 (where the compiler has chosen for i to live).
IL_0002: stloc.0 // i
System.Console.WriteLine(i + 10);
// Push the value of i back onto the stack.
IL_0007: ldloc.0 // i
// CSharp:
int i = 128;
// Compiles into:
// Push the value 128 (0x00000080) onto the stack
IL_0001: ldc.i4 80 00 00 00
// Store our 128 at location 0 (where the compiler has chosen for i to live).
IL_0002: stloc.0 // i
System.Console.WriteLine(i + 10);
// Push the value of i back onto the stack.
IL_0007: ldloc.0 // i
// Push 10 (0xA) onto the stack
IL_0008: ldc.i4.s 0A
// Add the two top values, leaving the result on top of the stack
IL_000A: add
// Call the static System.Console.WriteLine method, notice we’re passing a
// parameter by pushing its value onto the stack before a call instruction.
class MyClass { }
// Compiles into...
// Constructor declaration, remember a construcor is just a method under the hood.
MyClass..ctor:
// Push argument 0 onto the stack. Any CIL instance methods have an Argument 0
// which is a pointer to the current object the method being is called upon, 'this', in C#
IL_0000: ldarg.0
// Call our base class constructor on this.
class MyClass : object
{
public MyClass()
: base()
{ }
}
// call our first method, leaving the argument result on the stack top
IL_0001: call UserQuery.SideEffectOne
// jump to IL_000F if the first method returned false, pop from the stack
IL_0006: brfalse.s IL_000F
// call our second method, leaving the argument result on the stack top
IL_0008: call UserQuery.SideEffectTwo
// always jump to IL_0010, (no value popped!)
IL_000D: br.s IL_0010
// load integer value of 0 on to the stack top
IL_000F: ldc.i4.0
IL_0001: call SideEffectOne [0]
IL_0006: brfalse.s IL_000F []
IL_000F: ldc.i4.0 [0]
IL_0010: stloc.0 // p = 0 []
IL_0001: call SideEffectOne [1]
IL_0006: brfalse.s IL_000F []
IL_0008: call SideEffectTwo [p]
IL_000D: br.s IL_0010 [p]
IL_0010: stloc.0 // p []
bool p = ...;
bool q = ...;
bool r = p && q;
// p and q setup here…
// push p onto stack top
IL_0005: ldloc.0 // p [p]
// push q onto stack top
IL_0006: ldloc.1 // q [p, q]
// AND together top two stack values
IL_0005: ldloc.0 // p
IL_0006: brfalse.s IL_000B
IL_0008: ldloc.1 // q
IL_0009: br.s IL_000D
IL_000B: ldc.i4.0
IL_000D: stloc.2 // r