Jump to content

Common Intermediate Language/Stack

From Wikibooks, open books for an open world
ldarg <uint16>
Load an argument at a given position and push it onto the stack.
.method int32 Add(int32, int32)
{
    ldarg 0 // 2
    ldarg 1 // 4
    add
    ret
}

ldc.i4 2
ldc.i4 4
call int32 Add(int32, int32)
ldarg.s <uint8>
Load an argument at a given position and push it onto the stack. This takes up less space in bytecode compared to ldarg.
.method int32 Add(int32, int32)
{
    ldarg.s 0 // 2
    ldarg.s 1 // 4
    add
    ret
}

ldc.i4 2
ldc.i4 4
call int32 Add(int32, int32)
ldarg.0 - ldarg.3
Load an argument at a given position and push it onto the stack.
.method int32 Add(int32, int32)
{
    ldarg.s.0 // 2
    ldarg.s.1 // 4
    add
    ret
}

ldc.i4 2
ldc.i4 4
call int32 Add(int32, int32)
ldarga <uint16>
Load the address of an argument at a given position and push it onto the stack.
.method int32 Add(int32, int32)
{
    ldarga 0
    ldarga 1
    add
    ret
}

ldc.i4 2
ldc.i4 4
call int32 Add(int32, int32)
ldarga.s <uint8>
Load the address of an argument at a given position and push it onto the stack. This takes up less space in bytecode compared to ldarga.
.method int32 Add(int32, int32)
{
    ldarga.s 0
    ldarga.s 1
    add
    ret
}

ldc.i4 2
ldc.i4 4
call int32 Add(int32, int32)
ldc.i4 <int32>
Load a 32-bit (4-byte) integer and push it onto the stack.
.method int32 Add(int32, int32)
{
    ldarg 0
    ldarg 1
    add
    ret
}

ldc.i4 2
ldc.i4 4
call int32 Add(int32, int32)
ldc.i4.s <int8>
Load an 8-bit (1-byte) integer and push it onto the stack as 32-bit. This takes up less space in bytecode compared to ldc.i4.
.method int32 Add(int32, int32)
{
    ldarg 0
    ldarg 1
    add
    ret
}

ldc.i4.s 2
ldc.i4.s 4
call int32 Add(int32, int32)
ldc.i4.0 - ldc.i4.8
Load a 32-bit (4-byte) integer and push it onto the stack.
.method int32 Add(int32, int32)
{
    ldarg 0
    ldarg 1
    add
    ret
}

ldc.i4.2
ldc.i4.4
call int32 Add(int32, int32)
ldc.i4.m1 / ldc.i4.M1
Load -1 and push it onto the stack as 32-bit.
.method int32 Add(int32, int32)
{
    ldarg 0
    ldarg 1
    add
    ret
}

ldc.i4.m1
ldc.i4.M1
call int32 Add(int32, int32)
ldc.i8 <int64>
Load a 64-bit (8-byte) integer and push it onto the stack.
.method int64 Add(int64, int64)
{
    ldarg 0
    ldarg 1
    add
    ret
}

ldc.i8 2
ldc.i8 4
call int64 Add(int64, int64)
ldc.r4 <float32>
Load a 32-bit (4-byte) float and push it onto the stack.
.method float32 Add(float32, float32)
{
    ldarg 0
    ldarg 1
    add
    ret
}

ldc.r4 2.5
ldc.r4 4.5
call float32 Add(float32, float32)
ldc.r8 <float64>
Load a 64-bit (8-byte) float and push it onto the stack.
.method float64 Add(float64, float64)
{
    ldarg 0
    ldarg 1
    add
    ret
}

ldc.r8 2.5
ldc.r8 4.5
call float64 Add(float64, float64)
ldelem <type>
Load an element in an array and push it onto the stack.
// MyClass.MyArray[5]
ldfld int32[] MyClass::MyArray
ldc.i4 5
ldelem int32
ldelem <type>
Load an element in an array and push it onto the stack.
// MyClass.MyArray[5]
ldfld int32[] MyClass::MyArray
ldc.i4 5
ldelem int32
ldelem.i
Load an element in an array as a native int and push it onto the stack.
// MyClass.MyArray[5]
ldfld int32[] MyClass::MyArray
ldc.i4 5
ldelem.i
ldelem.i1
Load an element in an array as an int8 and push it onto the stack as an int32.
// (int32) MyClass.MyArray[5]
ldfld int8[] MyClass::MyArray
ldc.i4 5
ldelem.i1
ldelem.i2
Load an element in an array as an int16 and push it onto the stack as an int32.
// (int32) MyClass.MyArray[5]
ldfld int16[] MyClass::MyArray
ldc.i4 5
ldelem.i2
ldelem.i4
Load an element in an array as an int32 and push it onto the stack.
// MyClass.MyArray[5]
ldfld int32[] MyClass::MyArray
ldc.i4 5
ldelem.i4
ldelem.i8
Load an element in an array as an int64 and push it onto the stack.
// MyClass.MyArray[5]
ldfld int64[] MyClass::MyArray
ldc.i4 5
ldelem.i8
ldelem.r4
Load an element in an array as a float32 and push it onto the stack.
// MyClass.MyArray[5]
ldfld float32[] MyClass::MyArray
ldc.i4 5
ldelem.f4
ldelem.r8
Load an element in an array as a float64 and push it onto the stack.
// MyClass.MyArray[5]
ldfld float64[] MyClass::MyArray
ldc.i4 5
ldelem.f8
ldelem.ref
Load an element in an array and push it onto the stack as an object.
// (object) MyClass.MyArray[5]
ldfld int32[] MyClass::MyArray
ldc.i4 5
ldelem.ref
ldelem.u1
Load an element in an array as a uint8 and push it onto the stack as an int32.
// (int32) MyClass.MyArray[5]
ldfld unsigned int8[] MyClass::MyArray
ldc.i4 5
ldelem.u1
ldelem.u2
Load an element in an array as a uint16 and push it onto the stack as an int32.
// (int32) MyClass.MyArray[5]
ldfld unsigned int16[] MyClass::MyArray
ldc.i4 5
ldelem.u2
ldelem.u4
Load an element in an array as a uint32 and push it onto the stack as an int32.
// (int32) MyClass.MyArray[5]
ldfld unsigned int32[] MyClass::MyArray
ldc.i4 5
ldelem.u4
ldelem.u8
Load an element in an array as a uint64 and push it onto the stack as an int64.
// (int64) MyClass.MyArray[5]
ldfld unsigned int64[] MyClass::MyArray
ldc.i4 5
ldelem.u8
ldelema <type>
Load the address of an element as a <type> in an array and push it onto the stack.
// (managed pointer) MyClass.MyArray[5]
ldfld int32[] MyClass::MyArray
ldc.i4 5
ldelema int32
ldfld <type> <field>
Load a field's value, which is a <type>, and push it onto the stack.
ldfld int32 MyClass::MyField
ldflda <type> <field>
Load the address of a field, which is a <type>, and push it onto the stack.
ldflda int32 MyClass::MyField
ldflda <type> <field>
Load the address of a field, which is a <type>, and push it onto the stack.
ldflda int32 MyClass::MyField
ldftn <type> <method>
Load a pointer to a method, which returns <type>, referenced by <method> and push it onto the stack.
ldftn int32 MyClass::MyMethod()
ldind.i
Load a native int at an address and push it onto the stack.
ldarga 0
ldind.i
ldind.i1
Load an int8 at an address and push it onto the stack as an int32.
ldarga 0
ldind.i1
ldind.i2
Load an int16 at an address and push it onto the stack as an int32.
ldarga 0
ldind.i2
ldind.i4
Load an int32 at an address and push it onto the stack.
ldarga 0
ldind.i4
ldind.i8
Load an int64 at an address and push it onto the stack.
ldarga 0
ldind.i8
ldind.r4
Load an float32 at an address and push it onto the stack.
ldarga 0
ldind.r4
ldind.r8
Load an float64 at an address and push it onto the stack.
ldarga 0
ldind.r8
ldind.u1
Load an unsigned int8 at an address and push it onto the stack as an int32.
ldarga 0
ldind.u1
ldind.u2
Load an unsigned int16 at an address and push it onto the stack as an int32.
ldarga 0
ldind.u2
ldind.u4
Load an unsigned int32 at an address and push it onto the stack as an int32.
ldarga 0
ldind.u4
ldind.u8
Load an unsigned int64 at an address and push it onto the stack as an int64.
ldarga 0
ldind.u8
ldind.ref
Load an object at an address and push it onto the stack.
ldarga 0
ldind.ref
ldlen
Load the length of an array and push it onto the stack.
ldfld int32[] MyClass:MyArray
ldlen
ldloc <uint16>
Load the value of a local variable at a given position and push it onto the stack.
.method void Foo()
{
    .locals init (
        [0] int32 bar
    )

    ldc.i4.2
    stloc.0

    ldloc 0 // 2 (bar)
}
ldloc.s <uint8>
Load the value of a local variable at a given position and push it onto the stack. Takes up less space in bytecode compared to ldloc.
.method void Foo()
{
    .locals init (
        [0] int32 bar
    )

    ldc.i4.2
    stloc.0

    ldloc.s 0 // 2 (bar)
}
ldloc.0 - ldloc.3
Load the value of a local variable at a given position and push it onto the stack.
.method void Foo()
{
    .locals init (
        [0] int32 bar
    )

    ldc.i4.2
    stloc.0

    ldloc.0 // 2 (bar)
}
ldloca <uint16>
Load the address of a local variable and push it onto the stack.
.method void Foo()
{
    .locals init (
        [0] int32 bar
    )

    ldc.i4.2
    stloc.0

    ldloca 0 // bar
}
ldloca.s <uint8>
Load the address of a local variable and push it onto the stack. Takes up less space in bytecode compared to ldloca
.method void Foo()
{
    .locals init (
        [0] int32 bar
    )

    ldc.i4.2
    stloc.0

    ldloca.s 0 // bar
}
ldnull
Load null and push it onto the stack.
ldnull

...

brnull MyBranch
ldobj <type>
Pop an address off the stack, then push the value stored in that address.
ldflda int32 MyClass::MyInteger

...

ldobj int32
ldsfld <type> <field>
Load a static field's value, which is a <type>, and push it onto the stack.
ldsfld int32 MyClass::MyStaticField
ldsflda <type> <field>
Load the address of a static field, which is a <type>, and push it onto the stack.
ldsflda int32 MyClass::MyStaticField
ldstr <string>
Load a string and push it onto the stack.
ldstr "Hello, World!"
ldtoken <token>
Load a metadata token and push its runtime representation onto the stack.
ldtoken int32
ldvirtftn <type> <method>
Load the address of a virtual method, which returns <type>, and push it onto the stack.
ldvirtftn int32 MyClass::MyVirtualMethod()