惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cyber Attacks, Cyber Crime and Cyber Security
Project Zero
Project Zero
P
Proofpoint News Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cisco Blogs
V
Vulnerabilities – Threatpost
G
GRAHAM CLULEY
N
News | PayPal Newsroom
NISL@THU
NISL@THU
雷峰网
雷峰网
J
Java Code Geeks
Latest news
Latest news
aimingoo的专栏
aimingoo的专栏
Microsoft Azure Blog
Microsoft Azure Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cisco Talos Blog
Cisco Talos Blog
Hacker News: Ask HN
Hacker News: Ask HN
AWS News Blog
AWS News Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
The Exploit Database - CXSecurity.com
P
Privacy International News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
Vercel News
Vercel News
Spread Privacy
Spread Privacy
V2EX - 技术
V2EX - 技术
S
Schneier on Security
K
Kaspersky official blog
Recent Announcements
Recent Announcements
T
Threat Research - Cisco Blogs
B
Blog RSS Feed
S
SegmentFault 最新的问题
Security Archives - TechRepublic
Security Archives - TechRepublic
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
W
WeLiveSecurity
PCI Perspectives
PCI Perspectives
The GitHub Blog
The GitHub Blog
The Last Watchdog
The Last Watchdog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
Scott Helme
Scott Helme
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
量子位
A
Arctic Wolf

博客园 - 永红

东莞依时利诚聘java与.net方面的英才 项目管理笔记(观念) 项目管理笔记(概述) 【置顶】DLPrinter WEB打印组件第2次更新 也谈WEB打印(五):在IE的打印预览窗口中定义自己的用户接口 也谈WEB打印(四):让我们的模板支持打印,并根据内容动态的生成页面 也谈WEB打印(三):抛开IE,实现我们自己的打印模板 也谈WEB打印(二):简单的分析一下IE的打印原理并实现简单的打印和预览 也谈WEB打印(-):目前的几种方式及我们的任务 整理的几个常用的数据库维护的脚本 揭秘SQL Server 2000中的Bookmark Lookup 用MSIL剥开C#的外衣(一):方法参数ref、out、params和lock、for和foreach关键字 【翻译】MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API 【翻译】MSIL 教程(一) 设计模式实战:用Prototype模式提高系统的开发效率,用DynamicMethod、Flyweight模式提高系统的运行效率 用DynamicMethod提升ORM系统转换业务数据的性能 设计模式实战:在WinForm中用Command模式实现可以撤销的数据操作 把Sql数据转换为业务数据的几种方法 设计模式实战:组合型模式Composite,Adapter
【翻译】MSIL 教程(三):类和异常处理
永红 · 2007-08-16 · via 博客园 - 永红

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

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

指令:

  • .field定义类成员。和关键字publicprivatestatic等一起使用。

命令:

  • 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