• MSIL Hello World


    最近由于需要,开始阅读 MSIL 方面的东西。我读的是《.NET 探秘——MSIL 权威指南》(《Expert .NET 2.0 IL Assembler》中译版)。感觉没什么好说的,毕竟只要对 .NET 及其后面的东西了解一些,然后当做汇编来看,就好了。剩下的就是实践。

    如书上所言,前面已经有人做出了这项研究了,如 Anders Liu装配脑袋Flier Lu。前辈们都是老手了,我也不好说什么,毕竟我刚刚入门。

    这里就贴出昨晚写的一个 HelloWorld 程序吧。读了4天的收获。为了方便没学过 MSIL 的同志们,在上面都附上了实现同样功能的 C# 代码。

    嗯,高级的东西还不敢说,要再仔细看,多练习才行啊。

    .assembly extern mscorlib { auto }
    .assembly MyIlApp { }
    .module MyIlApp.exe
    
    .namespace MyIlApp
    {
        // public struct VC
        .class public value sealed auto VC
        {
            // public int val_int32;
            .field public int32 val_int32
            // public string val_string;
            .field public string val_string
        }
    
        // public sealed class MainClass
        .class public sealed auto ansi MainClass
        {
    
            // public static int _val;
            .field public static int32 _val
            
            // public static void check(int argument1)
            .method public static void check(int32) cil managed
            {
                // string temp;
                .locals init ([0]string temp)
                
                // if (MyIlApp.MainClass._val == argument1)
                // {
                //     System.Console.WriteLine("The value equals to the argument.");
                // }
                // else
                // {
                //     System.Console.WriteLine("The value does not equal to the argument.");
                // }
                ldsfld int32 MyIlApp.MainClass::_val
                ldarg.0
                beq TrueEqual
                ldstr "The value does not equal to the argument."
                call void [mscorlib]System.Console::WriteLine(string)
                br ThisIsEnd
                TrueEqual:
                ldstr "The value equals to the argument."
                call void [mscorlib]System.Console::WriteLine(string)
                
                // temp = argument1.ToString();    // 注意这里用 call 而不是 callvirt,因为 argument1 是 int32 类型,未装箱的时候没有V表
                ThisIsEnd:
                ldarga.s 0
                call instance string [mscorlib]System.Int32::ToString()
                stloc.0
                
                // System.Console.Write("The real value is:");
                ldstr "The real value is: "
                call void [mscorlib]System.Console::Write(string)
                
                // System.Console.WriteLine(temp);
                ldloc.0
                call void [mscorlib]System.Console::WriteLine(string)
                
                // return;
                ret
            }
            
            // public static void Main()
            .method public static void Main() cil managed
            {
                // .entrypoint 伪指令表示是程序入口点
                .entrypoint
                
                /* Test Case 1 */
                
                // string input;
                // int v;
                .locals init ([0] string input,
                              [1] int32 v)
                
                // System.Console.WriteLine("Hi. Please input a string:");
                ldstr "Hi. Please input a string:"
                call void [mscorlib]System.Console::WriteLine(string)
                
                // input = System.Console.ReadLine();
                call string [mscorlib]System.Console::ReadLine()
                stloc.0
                
                // System.Console.WriteLine(input);
                ldloc.0
                call void [mscorlib]System.Console::WriteLine(string)
                
                // v = System.Int32.Parse(input);
                ldloc.0
                call int32 [mscorlib]System.Int32::Parse(string)
                stloc.1
                
                // MyIlApp.MainClass._val = 9000;
                ldc.i4 9000
                stsfld int32 MyIlApp.MainClass::_val
                
                // System.Console.WriteLine(MyIlApp.MainClass._val.ToString());
                ldsflda int32 MyIlApp.MainClass::_val
                call instance string [mscorlib]System.Int32::ToString()
                call void [mscorlib]System.Console::WriteLine(string)
                
                // MyIlApp.MainClass.check(v);
                ldloc.1
                call void [MyIlApp]MyIlApp.MainClass::check(int32)
                
                /* Test Case 2 */
                
                
                // VC vc1;
                .locals init ([2] valuetype [MyIlApp]MyIlApp.VC vc1)
                
                // vc1.val_string = "Test string of VC";
                ldloca.s 2
                ldstr "Test string of VC"
                stfld string MyIlApp.VC::val_string
                
                // vc1.val_int32 = 8;
                ldloca.s 2
                ldc.i4.8
                stfld int32 MyIlApp.VC::val_int32
                
                // System.Console.WriteLine(vc1.val_string);
                ldloca.s 2
                ldfld string MyIlApp.VC::val_string
                call void [mscorlib]System.Console::WriteLine(string)
                
                // System.Console.WriteLine(vc1.val_int32.ToString());    // 《Expert .NET 2.0 IL Assembler》上说 ldflda “不能使用值类型的实例,也不能获取指向值类型实例的对象引用或指针”,有误。为了实现类似 a.X = 100(a 为 System.Drawing.Point 类型)这样的调用,需要用到 call 指令,也就需要用到 ldflda 而不是 ldfld;不过后者可以用在不访问实例函数/字段的情况下
                ldloca.s 2
                ldflda int32 MyIlApp.VC::val_int32
                call instance string [mscorlib]System.Int32::ToString()
                call void [mscorlib]System.Console::WriteLine(string)
                
                // return;
                ret
            }
            
        }
    }
  • 相关阅读:
    MyEclipse 常用快捷键
    javaEE基础08
    MySql卸载重新安装出现Start service没有响应的解决办法(64位)
    javaSE基础07
    为WAMP中的mysql设置密码(默认为空)
    javaSE基础06
    javaSE基础05
    vue框架构建项目流程
    阿里云或本地部署服务器(一)---nginx本地和服务器代理
    修改vue element Transfer 穿梭框里内容区的宽度
  • 原文地址:https://www.cnblogs.com/GridScience/p/4085189.html
Copyright © 2020-2023  润新知