zoukankan      html  css  js  c++  java
  • MSIL 教程(三):类和异常处理(转)

    转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857771.html

    续上文【翻译】MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API ,本文继续讲解类和异常处理。谨以这三篇译文纪念29年前的今日,那个让母亲今生难以忘记的幸福而又痛苦的日子。

    在前面的程序中,我们在Main函数中调用类函数,在本程序中,我们将徐希如何定义类。本程序包含2个类: Class1和SampleClass,Class1带有函数Main,在Main中生成SampleClass的一个实例。

    指令:

    • .field—定义类成员。和关键字public、private、static等一起使用。

    命令:

    • stsfld static field—用堆栈中的值替换静态字段的值。
    • ldfld field—把一个非静态字段装入堆栈。类实例的地址必须在调用本命令之前装入堆栈。
    • ldarg.n—把第n个参数装入堆栈。在非静态函数中,第0个参数是一个隐含的参数,代表this。
    • newobj constructor—用构造函数constructor生成一个类的实例。构造函数的参数必须在调用本函数之前先装入堆栈。一个类的实例会被生成并装入堆栈。
    • callvirt instance function—调用一个对象的后期绑定方法。

    代码:

    .assembly Classes {}
    /*
        class SampleClass
        {
            private int m_n;
            private string m_s;
            public static int nStatic = 10;
            public SampleClass(int n, string s)
            {
                m_n = n;
                m_s = s;
            }
     
            public int Number
            {
                get
                {
                    return m_n;
                }
            }
     
            public string String
            {
                get
                {
                    return m_s;
                }
            }
        };
     
        class Class1
        {
            [STAThread]
            static void Main(string[] args)
            {
                SampleClass o = new SampleClass(1, "Sample");
                Console.WriteLine(SampleClass.nStatic.ToString());
                Console.WriteLine(o.Number.ToString());
                Console.WriteLine(o.String);
            }
        }
    */
     
     
    .class private auto ansi beforefieldinit SampleClass
           extends [mscorlib]System.Object
    {
        .field private int32 m_n              // private int m_n;
        .field private string m_s             // private string m_s;
        .field public static int32 nStatic    // public static int nStatic;
     
        // 该私有静态构造函数由编译器生成
        // (用以初始化类的静态成员)
        .method private hidebysig specialname rtspecialname static
            void  .cctor() cil managed
        {
            .maxstack  8
     
            // *************************************************
            // nStatic = 10
            // *************************************************
            ldc.i4.s 10            // 把常量装入堆栈
            // stsfld 命令把静态字段的值替换成堆栈中的值
            stsfld     int32 SampleClass::nStatic
     
            ret
        }
     
        // 构造函数
        // public SampleClass(int n, string s)
        //
        .method public hidebysig specialname rtspecialname
            instance void  .ctor(int32 n, string s) cil managed
        {
            .maxstack  8
     
            // *************************************************
            // 调用基类的构造函数
            // *************************************************
            ldarg.0         // 把第0个参数装入堆栈(隐含指针this)
            // 调用类Object的构造函数
            call       instance void [mscorlib]System.Object::.ctor()
     
            // *************************************************
            // m_n = n
            // *************************************************
            ldarg.0         // 把第0个参数装入堆栈(隐含指针this)
            ldarg.1         // 把第1个参数装入堆栈(n)
            // 把n的值存入this.m_n
            stfld      int32 SampleClass::m_n
     
            // *************************************************
            // m_s = s
            // *************************************************
            ldarg.0         //把第0个参数装入堆栈(隐含指针this)
            ldarg.2         //把第2个参数装入堆栈(s)
            // 把s的值存入this.m_s
            stfld      string SampleClass::m_s
     
            ret
        }
     
        // 数字型属性
        .property instance int32 Number()
        {
            // 调用 get_Number
            .get instance int32 SampleClass::get_Number()
        }
     
        .method public hidebysig specialname instance int32
            get_Number() cil managed
        {
            .maxstack  8
     
            // 由编译器生成的变量
            // 译注:实际上,只有Debug版的才有,Release版的就直接返回m_n
            .locals ([0] int32 tmp)
     
            // *************************************************
            // 返回 m_n;
            // *************************************************
            ldarg.0
                      // 装入第0个参数(this)
            ldfld      int32 SampleClass::m_n
                      // 装入由堆栈栈顶指针指向的对象的字段
            stloc.0
                      // 存入第0个变量
            ldloc.0
                      // 把第0个变量装入堆栈(函数的返回值)
            ret
        }
     
        // 字符型属性
        .property instance string String()
        {
            .get instance string SampleClass::get_String()
        }
     
        .method public hidebysig specialname instance string
                get_String() cil managed
        {
            .maxstack  8
     
            // 由编译器生成的变量
            .locals ([0] string tmp)
     
            ldarg.0
                  // 装入第0个参数(this)
            ldfld      string SampleClass::m_s
                 // 装入由堆栈栈顶指针指向的对象的字段
            stloc.0
                 // 存入第0个变量
            ldloc.0
                 // 把第0个变量装入堆栈(函数的返回值)
            ret
        }
    }
     
     
    .class private auto ansi beforefieldinit Class1
           extends [mscorlib]System.Object
    {
        // public的缺省构造函数
        .method public hidebysig specialname rtspecialname
            instance void  .ctor() cil managed
        {
            .maxstack  8
     
            // *************************************************
            // 调用基类构造函数
            // *************************************************
            ldarg.0
                              // 装入thisr
            call       instance void [mscorlib]System.Object::.ctor()
                              // 类Objectr的构造函数
     
            ret
        }
     
        // Main 函数
        .method private hidebysig static void  Main(string[] args)
                cil managed
        {
            // 本方法为程序的入口点
            .entrypoint
     
            // 自定义属性
            .custom instance void [mscorlib]System.
                    STAThreadAttribute::.ctor() = ( 01 00 00 00 )
     
            .maxstack  8
     
            .locals ([0] class SampleClass o,
                     [1] int32 tmp)          // 由编译器生成
     
            // *************************************************
            // o = new SampleClass(1, "Sample");
            // *************************************************
            ldc.i4.1                        // 把常量1装入堆栈
            ldstr      "Sample"             // 把字符常量装入堆栈
            // 通过传入堆栈中的2个参数生成一个SampleClass的对象,
            // 并把他装入堆栈
            newobj     instance void SampleClass::.ctor(int32, string)
            stloc.0                         // 存入第0个变量
     
            // *************************************************
            // 访问静态类成员
            // Console.WriteLine(SampleClass.nStatic.ToString());
            // *************************************************
     
            //把静态字段的地址装入堆栈
            ldsflda    int32 SampleClass::nStatic
            // 为堆栈中的对象调用Int32::ToString
            call       instance string [mscorlib]System.Int32
                                ::ToString()
            // 调用静态的WriteLine,其传入参数是堆栈中的字符串
            call       void [mscorlib]System.Console
                       ::WriteLine(string)
     
            // *************************************************
            // 调用实例函数
            // Console.WriteLine(o.Number.ToString());
            // *************************************************
            ldloc.0                 // 装入第0个变量
            // 调用堆栈中对象的函数
            call   instance int32 SampleClass::get_Number()
            stloc.1                         // 存入第1个变量
            ldloca.s  tmp                   // 把地址装入堆栈
            call       instance string [mscorlib]System.Int32
                                ::ToString()
            call       void [mscorlib]System.Console
                            ::WriteLine(string)
     
            // *************************************************
            // 调用实例函数
            // Console.WriteLine(o.String);
            // *************************************************
            ldloc.0
            callvirt   instance string SampleClass::get_String()
            call       void [mscorlib]System.Console
                            ::WriteLine(string)
     
            // *************************************************
            ldstr "Press Enter to continue"
            call   void [mscorlib]System.Console
                        ::WriteLine(class System.String)
            call int32 [mscorlib]System.Console::Read()
            pop
            // *************************************************
     
            ret
        }
    }

    异常处理

    本程序使2个数相除,捕捉其除0异常。try/catch 块在MSIL中看起来像C#中的一样。

    命令:

    • leave.s label—离开try/catch等保护块。

    代码:

    .assembly Exception {}
     
    /*
                int x, y, z;
                string s;
     
                Console.WriteLine("Enter x:");
                s = Console.ReadLine();
                x = Int32.Parse(s);
     
                Console.WriteLine("Enter y:");
                s = Console.ReadLine();
                y = Int32.Parse(s);
     
                try
                {
                    z = x / y;
     
                    Console.WriteLine(z.ToString());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
     
    */
     
    .method static public void main() il managed
    {
        .entrypoint
        .maxstack 8
     
        .locals ([0] int32 x,
                 [1] int32 y,
                 [2] int32 z,
                 [3] string s,
                 [4] class [mscorlib]System.Exception e)
     
        //输入 x, y ...
     
        .try
        {
            // *************************************************
            // z = x / y;
            // *************************************************
            ldloc.0                 // 装入第0个变量
            ldloc.1                 // 装入第1个变量
            div                     // 相除
            stloc.2                 // 把结果存入第2个变量
     
            // *************************************************
            // Console.WriteLine(z.ToString());
            // *************************************************
            ldloca.s   z            // 装入z的地址
            call       instance string [mscorlib]System.Int32
                                       ::ToString()
            call       void [mscorlib]System.Console
                                       ::WriteLine(string)
     
            leave.s    END_TRY_CATCH        // 退出try
        }
        catch [mscorlib]System.Exception
        {
            stloc.s    e        // 存入由堆栈抛出的异常
     
            // *************************************************
            // Console.WriteLine(e.Message);
            // *************************************************
            ldloc.s    e                // load e
            callvirt   instance string [mscorlib]System.Exception
                                       ::get_Message()
            call       void [mscorlib]System.Console
                                       ::WriteLine(string)
            leave.s    END_TRY_CATCH        // 退出catch块
        }
     
    END_TRY_CATCH:
     
        ret
    }
  • 相关阅读:
    Java 基础
    Java 数据类型
    Spring 拦截器实现事物
    SSH 配置日记
    Hibernate 知识提高
    Jsp、Servlet
    leetcode 97. Interleaving String
    leetcode 750. Number Of Corner Rectangles
    leetcode 748. Shortest Completing Word
    leetcode 746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/6074339.html
Copyright © 2011-2022 走看看