转自: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 SampleClassextends [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 staticvoid  .cctor() cil managed{.maxstack  8// *************************************************// nStatic = 10// *************************************************ldc.i4.s 10            // 把常量装入堆栈// stsfld 命令把静态字段的值替换成堆栈中的值
        stsfld     int32 SampleClass::nStaticret}// 构造函数// public SampleClass(int n, string s)//
    .method public hidebysig specialname rtspecialnameinstance 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_sstfld      string SampleClass::m_sret}// 数字型属性
    .property instance int32 Number(){// 调用 get_Number.get instance int32 SampleClass::get_Number()}.method public hidebysig specialname instance int32get_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 stringget_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 Class1extends [mscorlib]System.Object
{// public的缺省构造函数.method public hidebysig specialname rtspecialnameinstance void  .ctor() cil managed{.maxstack  8// *************************************************// 调用基类构造函数// *************************************************ldarg.0// 装入thisrcall       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::ToStringcall       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.0callvirt   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 ecallvirt   instance string [mscorlib]System.Exception::get_Message()call       void [mscorlib]System.Console::WriteLine(string)leave.s    END_TRY_CATCH        // 退出catch块
    }END_TRY_CATCH:ret
}

转载于:https://www.cnblogs.com/anbylau2130/p/6074339.html

MSIL 教程(三):类和异常处理(转)相关推荐

  1. 【翻译】MSIL 教程(一)

    在网上发现了一个非常好的MSIL教程,可惜是英文版的,于是就翻译了一下,与大家共享, 原文http://www.codeguru.com/Csharp/.NET/net_general/il/arti ...

  2. MSIL 教程(一)

    在网上发现了一个非常好的MSIL教程,可惜是英文版的,于是就翻译了一下,与大家共享, 原文http://www.codeguru.com/Csharp/.NET/net_general/il/arti ...

  3. MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)...

    转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...

  4. Quartz教程三:Job与JobDetail介绍

    Quartz教程三:Job与JobDetail介绍 原文链接 | 译文链接 | 翻译:nkcoder | 校对: 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感 ...

  5. qpython3可视图形界面_PySide——Python图形化界面入门教程(三)

    PySide--Python图形化界面入门教程(三) --使用内建新号和槽 --Using Built-In Signals and Slots 上一个教程中,我们学习了如何创建和建立交互widget ...

  6. java泛型方法 通配符_Java泛型教程–示例类,接口,方法,通配符等

    java泛型方法 通配符 泛型是Java编程的核心功能之一,它是Java 5中引入的.如果您使用的是Java Collections ,并且版本5或更高版本,则可以肯定使用了它. 将泛型与集合类一起使 ...

  7. Java泛型教程–示例类,接口,方法,通配符等

    泛型是Java编程的核心功能之一,它是Java 5中引入的.如果您使用的是Java Collections ,并且版本5或更高版本,则可以肯定使用了它. 在集合类中使用泛型非常容易,但是它提供了比仅创 ...

  8. Java 结构体之 JavaStruct 使用教程三 JavaStruct 数组进阶

    经过前面两篇博客的介绍,相信对于 JavaStruct 的认识以及编程使用,读者已经有一定的基础了.只要理解和实践结合起来,掌握还是很容易的.下面进行一些数组使用方面的实例说明及演示. 在结构体类中使 ...

  9. SpringCloud 入门教程(三): 配置自动刷新

    Spring Cloud 入门教程(三): 配置自动刷新 之前讲的配置管理, 只有在应用启动时会读取到GIT的内容, 之后只要应用不重启,GIT中文件的修改,应用无法感知, 即使重启Config Se ...

最新文章

  1. Linux系统日志分析与管理(14)
  2. 性能:15个JavaScript本地存储技术的函数库和工具
  3. Python学习笔记007_图形用户界面[EasyGui][Tkinter]
  4. IOS之通知NSNotificationCenter的使用
  5. 顶级数据库行会Percona阿里全面解析下一代云数据库技术
  6. 2017西安交大ACM小学期 敏感词汇[AC自动机]
  7. 少儿编程100讲轻松学python(七)-pycharm怎么删除项目
  8. cmd命令操作Oracle数据库
  9. leetcode413. 等差数列划分(动态规划)
  10. 一台服务器上部署多个Terracotta的方法
  11. 被约谈后,丰巢道歉并让步了......
  12. 软件质量模型(学习笔记)
  13. Ant-编译构建(1)-HelloWorld
  14. 现代处理器设计——超标量处理器基础1-4
  15. UCF101动作识别数据集简介绍及数据预处理
  16. 用dxdiag命令show计算机系统配置
  17. 编码规则的发展历程(通俗版)
  18. ORA-01017: invalid username/password; logon denied ORA-02063: 紧接着line(源于DBLINKN~~~)
  19. maya Xgen导入UE4中,UE4毛发动力学
  20. FontAwesome-基本样式-1.1

热门文章

  1. python下载安装教程3.8.0-windows中安装Python3.8.0的实现方法
  2. 编程软件python下载-python 2.7官方版
  3. python利器跟python一样吗-VS code for python开发利器
  4. python切片语法-Python新手学习基础之数据类型——字符串的切片截取
  5. python基础知识整理-在Python中处理日期和时间的基本知识点整理汇总
  6. python基础题库-Python题库
  7. python学完可以干啥-Python学完可以做什么
  8. python与人工智能编程-人工智能与Python关系浅谈
  9. python编程培训多少钱-线下python培训要多少钱?
  10. python培训班一般多少钱-报个python培训班多少钱