CLR基础(二)_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > CLR基础(二)

CLR基础(二)

 2015/3/26 18:10:12  Mr.Jack  程序员俱乐部  我要评论(0)
  • 摘要:假设现在你编写了一个Program.cs的代码文件,那么在VisualStudio命令提示工具中执行以下命令:csc.exe/out:Program.exe/t:exe/r:mscorlib.dllProgram.cs这个命令行将指示C#编译器生成一个名为Program.exe的可执行文件(/out:Program.exe)。生成的文件属于Win32控制台应用程序类型(/t[target]:exe)。一个托管的PE文件由4个部分构成:PE32(+)头、CLR头、元数据以及IL。使用ILDasm
  • 标签:

假设现在你编写了一个Program.cs的代码文件,那么在Visual Studio命令提示工具中执行以下命令:
csc.exe /out:Program.exe /t:exe /r:mscorlib.dll Program.cs
这个命令行将指示C#编译器生成一个名为Program.exe的可执行文件(/out:Program.exe)。生成的文件属于Win32控制台应用程序类型(/t[target]:exe)。
一个托管的PE文件由4个部分构成:PE32(+)头、CLR头、元数据以及IL。使用ILDasm.exe(即IL Disassembler,IL反汇编器)可以检查一个托管PE文件中的元数据。下面讲一下关于ILDasm.exe的使用。
在"开始"菜单中找到"Visual Studio Tools",如图:

打开VS命令提示窗口,输入指令如:
ildasm D:\我的项目\程序测试\ILDasm使用测试\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe
这时会打开ildasm.exe,如图:

 

注意在指令中要使用绝对路径,否则ildasm.exe会找不到你所要反汇编的exe或dll文件。也可只输入ildasm,此时只会打开不加载任何exe或dll的ildasm.exe窗口:

 

还可以通过为Visual Studio添加外部工具来更方便地使用ILDasm.exe工具,如图:

"命令"那一栏其实就是选择ILDasm.exe所在的目录,如笔者的:
C:\Program Files\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe
现在就用一个实际的例子进一步讲解有关ILDasm.exe的使用。新建控制台应用程序,代码很简单:

1 class Program
2     {
3         static void Main(string[] args)
4         {
5             Console.WriteLine("ILDasm使用测试");
6             Console.ReadLine();
7         }
8 }

 保存生成后,打开ILDasm.exe,选择”文件”打开控制台应用程序生成的exe文件,如图:

 

随带附上ILDasm树状图的各种图标的说明:

鼠标双击树状图的子节点,便可看到相关的IL代码:

 

简单分析一下IL的代码及各种指令:
MANIFEST清单:MANIFEST是一个附加信息列表,主要包含程序集的一些属性,如程序集名称、版本号、哈希算法等;
ConsoleApplication1.Program类:

1 .class private auto ansi beforefieldinit ConsoleApplication1.Program
2        extends [mscorlib]System.Object
3 {
4 } // end of class ConsoleApplication1.Program

 

 

1).class,表示Program是一个类。并且它继承自程序集—mscorlib的System.Object类;
2)private,表示访问权限;
3)auto,表示程序的内存加载全部由CLR来控制;
4)ansi,是为了在没有托管代码与托管代码之间实现无缝转换。这里主要指C、C++代码等;
5)beforefieldinit,是用来标记运行库(CLR)可以在静态字段方法生成后的任意时刻,来加载构造器(构造函数);

.otor方法(一个构造器,或者说constructor):

1 .method public hidebysig specialname rtspecialname 
2         instance void  .ctor() cil managed
3 {
4   // 代码大小       7 (0x7)
5   .maxstack  8
6   IL_0000:  ldarg.0
7   IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
8   IL_0006:  ret
9 } // end of method Program::.ctor

 

1)cil managed:表示其中为IL代码,指示编译器编译为托管代码;
2).maxstack:表示调用构造函数.otor期间的评估堆栈(Evaluation Stack);
3)IL_0000:标记代码行开头;
4)ldarg.0:表示转载第一个成员参数,在实例方法中指的是当前实例的引用;
5)call:call一般用于调用静态方法,因为静态方法是在编译期就确定的。而这里的构造函数.otor()也是在编译期就制定的。而另一指令callvirt则表示调用实例方法, 它是在运行时确定的,因为如前述,当调用方法的继承关系时,就要比较基类与派生类的同名函数的实现方法(virtual和new),以确定调用的函数所属的Method Table;
6)ret:表示执行完毕,返回;

最后是Main()方法:

 1 .method private hidebysig static void  Main(string[] args) cil managed
 2 {
 3   .entrypoint
 4   // 代码大小       19 (0x13)
 5   .maxstack  8
 6   IL_0000:  nop
 7   IL_0001:  ldstr      bytearray (49 00 4C 00 44 00 61 00 73 00 6D 00 7F 4F 28 75   // I.L.D.a.s.m..O(u
 8                                   4B 6D D5 8B )                                     // Km..
 9   IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
10   IL_000b:  nop
11   IL_000c:  call       string [mscorlib]System.Console::ReadLine()
12   IL_0011:  pop
13   IL_0012:  ret
14 } // end of method Program::Main

 

1) .entrypoint指令表示CLR加载程序时,是首先从.entrypoint开始的,即从Main方法作为程序的入口函数;
2)ldstr:表示将字符串压栈,在这里就是将"Hello World." 压栈;
3)hidebysig:表示当把此类作为基类,存在派生类时,此方法不被继承,同上构造函数;
下面总结一下常用的IL指令:
1.newobj: 用于创建引用类型的对象;
2.ldstr:用于创建String对象变量;
3.newarr:用于创建数组型对象;
4.box:在值类型转换为引用类型的对象时,将值类型拷贝纸托管堆上分配内存;
现在对ILDasm的了解先告一段落,下面继续CLR之旅。上面讲到的控制台应用程序生成的exe文件其实就是一个程序集。CLR对程序集的解释是:程序集是一个或多个类型定义文件及资源文件的集合。为程序集添加资源文件,比如说常见的为一个Winform桌面程序添加一个自己的特色图标,可以在Visual Studio中选择项目”属性”,然后在”应用程序”选项卡中添加资源文件。

嵌入图标后,应用程序的可执行文件便会显示自己特有的图标。

  • 相关文章
发表评论
用户名: 匿名