MSIL 教程(三):类和异常处理

2024-04-17 01:38
文章标签 异常 教程 处理 msil

本文主要是介绍MSIL 教程(三):类和异常处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

续上文【翻译】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
}
Downloads
Download source - 43 Kb

 

这篇关于MSIL 教程(三):类和异常处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/910471

相关文章

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

Springboot处理跨域的实现方式(附Demo)

《Springboot处理跨域的实现方式(附Demo)》:本文主要介绍Springboot处理跨域的实现方式(附Demo),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录Springboot处理跨域的方式1. 基本知识2. @CrossOrigin3. 全局跨域设置4.

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

MySQL Workbench 安装教程(保姆级)

《MySQLWorkbench安装教程(保姆级)》MySQLWorkbench是一款强大的数据库设计和管理工具,本文主要介绍了MySQLWorkbench安装教程,文中通过图文介绍的非常详细,对大... 目录前言:详细步骤:一、检查安装的数据库版本二、在官网下载对应的mysql Workbench版本,要是

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

Java异常架构Exception(异常)详解

《Java异常架构Exception(异常)详解》:本文主要介绍Java异常架构Exception(异常),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. Exception 类的概述Exception的分类2. 受检异常(Checked Exception)

Python实现自动化接收与处理手机验证码

《Python实现自动化接收与处理手机验证码》在移动互联网时代,短信验证码已成为身份验证、账号注册等环节的重要安全手段,本文将介绍如何利用Python实现验证码的自动接收,识别与转发,需要的可以参考下... 目录引言一、准备工作1.1 硬件与软件需求1.2 环境配置二、核心功能实现2.1 短信监听与获取2.

通过Docker Compose部署MySQL的详细教程

《通过DockerCompose部署MySQL的详细教程》DockerCompose作为Docker官方的容器编排工具,为MySQL数据库部署带来了显著优势,下面小编就来为大家详细介绍一... 目录一、docker Compose 部署 mysql 的优势二、环境准备与基础配置2.1 项目目录结构2.2 基

Linux安装MySQL的教程

《Linux安装MySQL的教程》:本文主要介绍Linux安装MySQL的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux安装mysql1.Mysql官网2.我的存放路径3.解压mysql文件到当前目录4.重命名一下5.创建mysql用户组和用户并修