首页 > 代码库 > MSIL Hello World

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        }            }}

 

MSIL Hello World