.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 2:0:0:0
}
.assembly CILTypes
{
.ver 1:0:0:0
}
.module CILTypes.dll
.namespace MyNamespace
{
//definitions for interface
.class public interface IMyInterface{}
//definitions for class
.class public MyBaseClass
{
//fields
.field private string stringField
.field private int32 intField
//constructor
.method public hidebysig specialname rtspecialname
instance void .ctor(string s, int32 i) cil managed
{
.maxstack 8
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
nop
nop
ldarg.0
ldarg.1
stfld int32 MyNamespace.MyBaseClass::stringField
ldarg.0
ldarg.2
stfld string MyNamespace.MyBaseClass::intField
nop
ret
}
//static constructor
.method public hidebysig specialname rtspecialname
static void .cctor()
{
.maxstack 8
nop
ret
}
//property
.method public hidebysig specialname
instance string get_TheString() cil managed
{
.maxstack 1
.locals init ([0] string CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string MyNamespace.MyBaseClass::stringField
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
}
.method public hidebysig specialname
instance void set_TheString(string 'value') cil managed
{
.maxstack 8
nop
ldarg.0
ldarg.1
stfld string MyNamespace.MyBaseClass::stringField
ret
}
.property instance string TheString()
{
.get instance string MyNamespace.MyBaseClass::get_TheString()
.set instance void MyNamespace.MyBaseClass::set_TheString(string)
}
}
//inherit class and implement interface
.class public MyDerivedClass extends MyNamespace.MyBaseClass
implements MyNamespace.IMyInterface{}
//definitions for Structure
.class public sealed MyStruct extends [mscorlib]System.ValueType{}
.class public sealed value MyStruct2{}
//definitions for Enum
.class public sealed MyEnum extends [mscorlib]System.Enum
{
.field public static literal valuetype
MyNamespace.MyEnum A = int32(0)
.field public static literal valuetype
MyNamespace.MyEnum B = int32(1)
.field public static literal valuetype
MyNamespace.MyEnum C = int32(2)
.field public static literal valuetype
MyNamespace.MyEnum D = int32(3)
}
.class public sealed enum MyEnum2
{
.field public static literal valuetype
MyNamespace.MyEnum E = int32(4)
}
//definitions for Generic
.class public MyGenericClass`1<T>{}
.class public Generic_Def
{
.field private class [mscorlib]System.Collections.Generic.List`1<int32> intList
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 8
ldarg.0
newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
stfld class [mscorlib]System.Collections.Generic.List`1<int32> MyNamespace.Generic_Def::intList
ldarg.0
nop
ret
}
// difinition for local variable
.method public hidebysig static void MyLocalVariables() cil managed
{
.maxstack 8
// difine three local variables
.locals init ([0] string myStr, [1] int32 myInt, [2] object myObj)
//load the string to virtual stack
ldstr "CIL code is cool"
// pop the element and store it in variable[0]
stloc.0
// load const i4 with value being 3
ldc.i4 3
// pop the element and store it in variable[1]
stloc.1
// create an object on stack
newobj instance void [mscorlib]System.Object::.ctor()
// pop the element and store it in variable[2]
stloc.2
ret
}
}
}
部分CIL 操作码
操作码 作用
add, sub, mul, div, rem 用于两个数加减乘除求模
add, or, not, xor 用于在两个值上进行二进制操作
ceq, cgt, clt 用不同的方法比较两个在栈上的值,ceq:是否相等;cgt:是否大约;clt:是否小于
box, unbox 在引用类型和值类型之间转换
ret 退出方法和返回一个值
beq, bgt, ble, blt, switch 控制方法中的条件分支,beg:如果相等就中止到代码标签;bgt:如果大于就中止到代码标签;
ble:如果小于等于就中止到代码标签;blt:如果小于就中止到代码标签;
所有的分支控制操作码都需要给出一个CIL代码标签作为条件为真的跳转目的
br.s (无条件)中止到代码标签
call 调用一个成员
nearer, newobj 在内存中创建一个新的数组或新的对象类型
主要的入栈CIL操作码 (ld 加载)
操作码 作用
ldarg (及多个变化形式) 加载方法的参数到栈中。除了泛型ldarg(需要一个索引作为参数),还有后其他很多的变化形式。
eg. 有个数字后缀的ldarg操作码来指定需要加载的参数。同时还有很多ldarg的变化形式允许加载
指定的数据类型(ldarg_i4, 加载int32)和值(ldarg_i4_5 加载一个值为5的int32)
ldc (及多个变化形式) 加载一个常数到栈中
ldfld (及多个变化形式) 加载一个对象实例的成员到栈中
ldloc (及多个变化形式) 加载一个本地变量到栈中
ldobj 获得一个堆对象的所有数据,并将它们放置到栈中
ldstr 加载一个字符串数据到栈中
主要的弹出栈操作码 (st 存储)
操作码 作用
pop 删除当前栈顶的值,但是并不影响存储的值
starg 存储栈顶的值到给出方法的参数,根据索引确定这个参数
stloc (及多个变化形式) 弹出当前栈顶的值并存储在一个本地变量列表中,根据所以确定这个参数
stobj 从栈中复制一个特定的类型到指定的内存地址
stfld 用从栈中获得的值替换对象成员的值