翔如菲菲

其实天很蓝,阴云总会散;其实海不宽,此岸连彼岸.

导航

MSIL 教程(一)

打印字符串

PrintString 就是MSIL版的 Hello, World

在代码中用到的MSIL指令如下:

l          .entrypoint 定义程序的入口点(该函数在程序启动的时候由.NET 运行库调用)

l          .maxstack定义函数代码所用堆栈的最大深度。C#编译器可以对每个函数设置准确的值, 在例子中,我把他设为8

用到的MSIL命令如下:

  • ldstr string把一个字符串常量装入堆栈。
  • call function(parameters)调用静态函数。函数的参数必须在函数调用前装入堆栈。
  • pop取出栈顶的值。当我们不需要把值存入变量时使用。
  • ret从一个函数中返回。

调用静态函数很简单。我们把函数的参数压入堆栈,调用函数,然后从堆栈中读取函数的返回值(如果是非void函数)。Console.WriteLine 就是一个这样的函数。

下面是代码:

.assembly PrintString {}

/*

    Console.WriteLine("Hello, World)"

*/

.method static public void main() il managed

{

    .entrypoint             // 该函数是程序的入口

    .maxstack 8

    // *****************************************************

    // Console.WriteLine("Hello, World)";

    // *****************************************************

    ldstr "Hello, World"        // 把字符串压入堆栈

    // 调用静态的System.Console.Writeline函数

    // (函数移除栈顶的字符串)

    call   void [mscorlib]System.Console::WriteLine

                                 (class System.String)

    // *****************************************************

    ldstr "Press Enter to continue"

    call   void [mscorlib]System.Console::WriteLine

                                 (class System.String)

    // 调用 System.Console.Read 函数

    call int32 [mscorlib]System.Console::Read()

    // pop 指令移除栈顶元素

    // (移除由Read()函数返回的数字

    pop

    // *****************************************************

    ret

}


赋值

该程序给一个变量赋与int值并把它打印到控制台窗口。

命令:

  • ldc.i4.n把一个 32位的常量n装入堆栈
  • stloc.n把一个从堆栈中返回的值存入第nn08)个局部变量
  • ldloc.n把第n个变量装入堆栈

代码:

.assembly XequalN {}

// int x;

// x = 7;

// Console.WriteLine(x);

.method static public void main() il managed

{

    .entrypoint

    .maxstack 8

    .locals init ([0] int32 x)  // 分配一个局部变量

    // *****************************************************

    // x = 7;

    // *****************************************************

    ldc.i4.7                    // 把常量7装入堆栈

    stloc.0                     // 把堆栈中的值存入第0个变量

    // *****************************************************

    // Console.WriteLine(x);

    // *****************************************************

    ldloc.0                     // 把第0个变量装入堆栈

    call void [mscorlib]System.Console::WriteLine(int32)

    ret

}


数据运算

本程序从控制台读取2个数字,对它们进行简单的运算,然后显示结果。

命令:

  • add—2个值相加。命令的参数必须在调用前装入堆栈,该函数从堆栈中移除参数并把运算后的结果压入堆栈。
  • sub— 2个值相减。
  • mul— 2个值相乘。

代码片段:

.assembly Operations {}

/*

// 程序的C#代码:

            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);

 

            z = x + y;

            Console.Write("x + y = ");

            Console.Write(z);

            Console.WriteLine("");

 

            z = x - y;

            Console.Write("x - y = ");

            Console.Write(z);

            Console.WriteLine("");

 

            z = x * y;

            Console.Write("x * y = ");

            Console.Write(z);

            Console.WriteLine("");

*/

 

.method static public void main() il managed

{

    .entrypoint

    .maxstack 8

 

    .locals init ([0] int32 x,

           [1] int32 y,

           [2] int32 z,

           [3] string s)

 

    // *****************************************************

    // Console.WriteLine("Enter x:");

    // *****************************************************

    ldstr      "Enter x:"       // 把字符装入堆栈

call       void [mscorlib]System.Console::WriteLine(string)

 

    // *****************************************************

    // s = Console.ReadLine();

    // *****************************************************

    call       string [mscorlib]System.Console::ReadLine()

    stloc.3                     // 把值存入第3个变量

 

    // *****************************************************

    // x = Int32.Parse(s);

    // *****************************************************

    ldloc.3                     // 把第3个变量装入堆栈

 

    // 调用 System.Int32::Parse(string)函数

    // 把字符串从堆栈中移除并把解析的结果——int值压入堆栈

    call       int32 [mscorlib]System.Int32::Parse(string)

 

    stloc.0                     // 把值存入第0个变量

 

    // *****************************************************

    // 和变量y的一些运算

    // *****************************************************

    ldstr      "Enter y:"

               // 装入字符串

    call       void [mscorlib]System.Console::WriteLine(string)

               // 调用

    call       string [mscorlib]System.Console::ReadLine()

               // 调用

    stloc.3

               //把值存入第3个变量

    ldloc.3

               //把第3个变量装入堆栈

    call       int32 [mscorlib]System.Int32::Parse(string)

               // 调用

    stloc.1

               //把值存入第1个变量

 

    // *****************************************************

    // z = x + y;

    // *****************************************************

    ldloc.0             //把第0个变量装入堆栈

    ldloc.1             //把第1个变量装入堆栈

 

    // 把这2个值从堆栈中移除,把结果压入堆栈

add

 

    stloc.2             //把值存入第2个变量

 

    // *****************************************************

    // Console.Write("x + y = ");

    // *****************************************************

    ldstr      "x + y = "          // load string onto stack

    call       void [mscorlib]System.Console::Write(string)

 

    // *****************************************************

    // Console.Write(z);

    // *****************************************************

    ldloc.2                    //把第2个变量装入堆栈

    call       void [mscorlib]System.Console::Write(int32)

 

    // *****************************************************

    // Console.WriteLine("");

    // *****************************************************

    ldstr      ""                  //装入字符串

    call       void [mscorlib]System.Console::WriteLine(string)

 

    //相减和相乘运算过程与上面相同

 

    ret

}

posted on 2009-05-26 15:54  翔如飞飞  阅读(268)  评论(0编辑  收藏  举报