Friday, April 5, 2013

Common CIL incantations

Since I recently decided to try my hand at CIL by writing assemblies by hand, I'm now writing this post where I will list down a couple of basic CIL routines.

I am of course primarily writing this post for myself so that future me will have a reference if he (I?) decides to do something with it again.

Hello World
.assembly helloworld {}
.assembly extern mscorlib {}

.method public static void Main () {
    .entrypoint
    ldstr "Hello World!"
    call void [mscorlib]System.Console::WriteLine(string)
    ret
}
Including external assemblies
.assembly extern mscorlib {}
Pushing a 32 bit integer constant to the stack
ldc.i4 42
Pushing a 64 bit integer constant to the stack
ldc.i8 829190
Pushing a string constant to the stack
ldstr "Andreas"
Declaring and loading unnamed variables (popping elements off the stack)
.locals init (int32, string) // init specifies that the variables must be initialized to the default types
ldc.i4 42
stloc.0 // storing the 32 bit integer at position 0 by popping it off the stack
ldstr "CIL"
stloc.1
Defining a class
.class MathHelpers extends [mscorlib]System.Object {
    .method void .ctor() { // Constructor
        ldarg.0
        call instance void [mscorlib]System.Object::.ctor()
    }

    .method public instance int32 Inc(int32) { // Instance method; the instance keyword can be omitted
        ldarg.0
        ldc.i4.1
        add
        ret
    }
    
    .method public static int32 Add(int32 n, int32 m) {  // Static method
        ldarg n
        ldarg m
        add
        ret
    }
}
Invoking methods from external assemblies
.assembly extern mscorlib {}

// ...

ldstr "Writelining"
call void [mscorlib]System.Console::WriteLine(string)
Invoking an instance method
.locals init (class MathHelpers mh)

newobj instance void MathHelpers::.ctor()
stloc mh

call instance void MathHelpers::Show()
Invoking a static method
call void MyNamespace.MyClass::StaticMethod()
Using an array
.locals init (string[] names);

.ldc.i4.4 // the int32 constant that's used for the size of the array: new string[4]
newarr string
stloc names

// Add element 0
ldloc names
ldc.i4.0 // array index
ldstr "Dreas"
stelem.ref

// Add element 1
ldloc names
ldc.i4.1 // array index
ldstr "John"
stelem.ref