Notas de estudio de C # (dos) -IL preliminar

Continúe aprendiendo el código IL, ahora veremos cómo se ejecuta el dispositivo de atributo de uso común: El
código C # es el siguiente:

using System;
namespace ConsoleApp1
{
    
    
    public class MyClass
    {
    
    
        public MyClass(int v)
        {
    
    
            val = v;
        }
        private int val {
    
     get; set; }
        public int GetVal()
        {
    
    
            return val++;
        }
    }
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            MyClass myClass = new MyClass(12);
            Console.WriteLine(myClass.GetVal());
        }
    }
}

Resultado de la operación: el
Inserte la descripción de la imagen aquí
código IL obtenido después de la descompilación es el siguiente:

 .namespace ConsoleApp1 // .namespace:命名空间
{
    
    
    .class public auto ansi beforefieldinit ConsoleApp1.MyClass     //.class 类标识 auto 类的布局方式 ansi 指定类中的字符串必须转换成ANSI字符
        extends [System.Runtime]System.Object                       //.NET Core中beforfieldinit特性时当有一个静态变量被使用时就初始化所有静态变量-  //所有对象继承自基类object
    {
    
    
        // Fields
        .field private int32 '<val>k__BackingField'                 //.field声明字段
        //字段自动生成的两个属性 .custom 自定义方法 .ctor()构造方法  .cctor静态构造方法
        .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
            01 00 00 00
        )
        .custom instance void [System.Diagnostics.Debug]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [System.Diagnostics.Debug]System.Diagnostics.DebuggerBrowsableState) = (
            01 00 00 00 00 00 00 00
        )
        // Methods
        .method public hidebysig specialname rtspecialname //.method 方法标识 hidebysig 隐藏签名 specialname 特定方法标识
            instance void .ctor (
                int32 v
            ) cil managed //cil managed 标识IL中实现的方法 
        {
    
    
            // Method begins at RVA 0x2050
            // Code size 17 (0x11)
            .maxstack 8 //.maxstack标识JIT它需要保留该方法的最大堆栈大小--just In Time Complier 将中间语言编译成计算机可以理解的机器码

            IL_0000: ldarg.0    //将参数0位加载到堆栈 this
            IL_0001: call instance void [System.Runtime]System.Object::.ctor()    //调用构造方法初始化类
            IL_0006: nop    //nothing to do 
            IL_0007: nop    //nothing to do
            IL_0008: ldarg.0    //将参数0位加载到堆栈 this
            IL_0009: ldarg.1    //将参数1位加载到堆栈(1位为真正的参数)
            IL_000a: call instance void ConsoleApp1.MyClass::set_val(int32)    //执行类myclass中 val 属性器的set方法
            IL_000f: nop    //nothing to do 
            IL_0010: ret    //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
        } // end of method MyClass::.ctor


        .method private hidebysig specialname    //.method 方法标识 hidebysig 隐藏签名 specialname 特定方法标识
            instance int32 get_val () cil managed    //cil managed 标识IL中实现的方法
{
    
    
            .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
                01 00 00 00
            )
            // Method begins at RVA 0x2062
            // Code size 7 (0x7)
            .maxstack 8    //.maxstack标识JIT它需要保留该方法的最大堆栈大小--just In Time Complier 将中间语言编译成计算机可以理解的机器码
            IL_0000: ldarg.0    //将参数0位加载到堆栈 this
            IL_0001: ldfld int32 ConsoleApp1.MyClass::'<val>k__BackingField' /从堆栈0位读取值
            IL_0006: ret    //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
        } // end of method MyClass::get_val

        .method private hidebysig specialname
            instance void set_val (
                int32 'value'
            ) cil managed
{
    
    
            .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
                01 00 00 00
            )
            // Method begins at RVA 0x206a
            // Code size 8 (0x8)
            .maxstack 8 //.maxstack标识JIT它需要保留该方法的最大堆栈大小--just In Time Complier 将中间语言编译成计算机可以理解的机器码
            IL_0000: ldarg.0    //将参数0位加载到堆栈 this
            IL_0001: ldarg.1    //将参数1位加载到堆栈
            IL_0002: stfld int32 ConsoleApp1.MyClass::'<val>k__BackingField'  //替换在对象引用或指针的字段中存储的值
            IL_0007: ret   //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
        } // end of method MyClass::set_val
        .method public hidebysig
            instance int32 GetVal () cil managed
{
    
    
            // Method begins at RVA 0x2074
            // Code size 24 (0x18)
            .maxstack 2
            .locals init (
                [0] int32,
                [1] int32
            ) //初始化局部变量


            IL_0000: nop    //nothing todo 
            IL_0001: ldarg.0  //将索引为 0 的参数加载到计算堆栈上
            IL_0002: call instance int32 ConsoleApp1.MyClass::get_val() //调用get_val() 获取到val 的值
            IL_0007: ldc.i4.1  //将整数值 1 作为 int32 推送到计算堆栈上
            IL_0008: add    //执行相加命令
            IL_0009: stloc.0 //从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中
            IL_000a: ldarg.0 // 将索引为 0 的参数加载到计算堆栈上
            IL_000b: ldloc.0 //将索引 0 处的局部变量加载到计算堆栈上
            IL_000c: call instance void ConsoleApp1.MyClass::set_val(int32) //调用set_val 设置val 值
            IL_0011: nop //nothing todo
            IL_0012: ldloc.0 //将索引 0 处的局部变量加载到计算堆栈上
            IL_0013: stloc.1 //从计算堆栈的顶部弹出当前值并将其存储到索引 1 处的局部变量列表中
            IL_0014: br.s IL_0016 //跳转IL_0016
            IL_0016: ldloc.1 //将索引 1 处的局部变量加载到计算堆栈上
            IL_0017: ret //返回
        } // end of method MyClass::GetVal

        // Properties
        .property instance int32 val()
{
    
    
            .get instance int32 ConsoleApp1.MyClass::get_val()
            .set instance void ConsoleApp1.MyClass::set_val(int32)
        }
    } // end of class ConsoleApp1.MyClass
    .class private auto ansi beforefieldinit ConsoleApp1.Program
        extends [System.Runtime]System.Object
    {
    
    
        // Methods
        .method private hidebysig static
            void Main (
                string[] args
            ) cil managed
{
    
    
            // Method begins at RVA 0x2098
            // Code size 22 (0x16)
            .maxstack 1
            .entrypoint
            .locals init (
                [0] class ConsoleApp1.MyClass myClass
            ) //局部变量 初始化

            IL_0000: nop
            IL_0001: ldc.i4.s 12 // ldc.i4.s 命令 将提供的 int8 值作为 int32 推送到计算堆栈上 --初始化
            IL_0003: newobj instance void ConsoleApp1.MyClass::.ctor(int32) //调用构造方法初始化 newobj
            IL_0008: stloc.0 //从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中
            IL_0009: ldloc.0 //将索引 0 处的局部变量加载到计算堆栈上
            IL_000a: callvirt instance int32 ConsoleApp1.MyClass::GetVal() //调用方法 getval() 计算
            IL_000f: call void [System.Console]System.Console::WriteLine(int32) //调用输出方法
            IL_0014: nop
            IL_0015: ret //return
        } // end of method Program::Main
        .method public hidebysig specialname rtspecialname
            instance void .ctor () cil managed //构造函数
{
    
    
            // Method begins at RVA 0x20ba
            // Code size 8 (0x8)
            .maxstack 8
            
            IL_0000: ldarg.0 //this
            IL_0001: call instance void [System.Runtime]System.Object::.ctor() //调用基类的构造函数
            IL_0006: nop
            IL_0007: ret
        } // end of method Program::.ctor
    } // end of class ConsoleApp1.Program
}

Casi todas las palabras clave y funciones en cada línea se anotan sin explicación adicional.


Aprende un poco todos los días, siempre habrá ganancias.

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/xuetian0546/article/details/107374813
Recomendado
Clasificación