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
    }
  • 相关阅读:
    Delphi Try Except 实例
    如何有效地让一个“ParentFont = False”子控件使用与父母相同的字体名称?
    WPF的本质:数据和行为
    WPF-触发器
    WPF TextBox 验证输入
    wpf数据绑定更新通知
    asp.net *.ashx类型的文件使用说明
    asp.net 定时间点执行任务的简易解决办法
    asp.net 页面延时五秒,跳转到另外的页面
    Asp.net 基于Cookie简易的权限判断
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/6074339.html
Copyright © 2011-2022 走看看