曙海教育集团论坛开发语言培训专区Microsoft.NET Framework → Microsoft.Net框架程序设计, Part I: Basics of the Microsoft .NET Framework(中文)


  共有6124人关注过本帖树形打印

主题:Microsoft.Net框架程序设计, Part I: Basics of the Microsoft .NET Framework(中文)

美女呀,离线,留言给我吧!
wangxinxin
  1楼 个性首页 | 博客 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:青蜂侠 帖子:1393 积分:14038 威望:0 精华:0 注册:2010-11-12 11:08:23
Microsoft.Net框架程序设计, Part I: Basics of the Microsoft .NET Framework(中文)  发帖心情 Post By:2010-12-15 10:23:04

English Version go here.

By Alva Chien

Part I: Basics of the Microsoft .NET Framework

Chapter 1: The Architecture of the .NET framework Development Platform

1.       .Net中的common language runtime (CLR) 是一个可以被多个不同语言使用的runtime. 不管使用哪种编译器,所生成的结果都是一个managed module. 一个managed module是一个标准的Windows Portable executable (PE) 文件,这个文件必须由CLR来执行.

一个managed module的组成:

Part

Description

PE Header

标准的 Windows PE header, 类似于Common Object File Format (COFF) header. 这个header包含了文件类型: GUI, CUI, or DLL, 它同样包含了一个文件创建时的时间戳. 对只包含IL代码的的modulesPE header中的大部分信息被忽略. 对包含native CPU代码的module,这个header包含了关于native CPU代码的信息.

CLR Header

包含了一个managed module所必须的信息(CLR和其工具解析) . 这个header包含了所需的CLR版本和一些状态标志位, managed module的入口方法(Main方法,一个MethodDef metadata token), metadata的位置/大小, 资源, strong name, 一些标志位和其他信息.

Metadata

每个managed module都包含metadata. 这些表有两种类型: 定义typesmembers的的表和定义Referencedtypemembers的表.

Intermediate language (IL) code

由编译器编译的代码,真正执行时候CLR会将IL代码编译为native CPU instructions.

2.       一个 assembly是一个或多个managed modules/资源文件的逻辑组合, 它是最小的可重用,拥有版本信息和安全信息的单元. PE文件包含一块叫做manifest的数据块. 一个manifest是另一个metadata tables的集合. 这些tables定义了组成一个assembly的文件, 由这些文件定义的exported types, 跟这个assembly关联的资源或数据文件. 一个典型的例子: 把一些较少使用的types或资源定义在assembly的一个独立文件中,这个文件只会在其中的type或资源被使用的时候才被加载.

3.       可以通过查找MSCorEE.dll 文件来判断.NET是否被安装,这个文件位于%windir%\system32 文件夹中. 但是,一台机器允许同时安装几个版本的.Net Framewor.可以通过查看一下注册表的键值来判断当前.NET的版本: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy

4.       如何装载 CLR:

  • 当创建一个EXE assembly, 编译器/链接器在生成的assembly’s PE file header嵌入一些特别的信息在.text section.
  • 当创建一个DLL assembly, 如果一个unmanaged程序调用LoadLibrary 装载它, 这个DLL’s 入口函数知道如果装载CLR来正确处理assembly中的代码.

5.       当创建一个EXE assembly, 一个的6字节的x86 sub function被嵌入到.text section: JMP _CoreExeMain. 这个_CoreExeMain函数从MSCorEE.dll导入, 这个MSCoreEE.dll (Microsoft Component Object Runtime Execution Engine) assembly file’s .idata section定义了引用. 所以当assembly像正常程序一样启动时, MSCoreEE.dll被导入到这个进程的地址空间, 这时_CorExemain 函数的地址被获取,同时JMP instruction被执行. 这个函数将初始化CLR并且查找这个可执行assembly’s CLR header的可执行入口方法,这个方法的IL代码将被编译为native CPU instructions 随后CLR跳转这个native code, 这时,程序已经启动.

6.       当创建一个DLL assembly, 一个类似的6字节长的x86 stub function被嵌入到.text section: JMP _CorDllMain. _CorDllMain 函数同样从MSCorEE.dll中引入, 这个DLL’s .idata section 中包含MSCorEE.dll的引用定义. 所以, LoadLibrary 执行时_CorDllMain 被调用来初始化CLR并返回给应用程序来继续执行.

7.       这个6字节的stub function仅仅在非Windows XP系统中被添加. Windows XP以及以后版本中, OS loader检查嵌入managed code的文件的PE file headerdirectory entry 14. (IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR定义在WinNT.h) 如果这个directory entry存在并且拥有一个非0, OS loader忽略这个文件的导入 (.idata) section并且自动装载MSCorEE.dll到进程的地址空间并直接跳转到对应的函数.

8.       最后一个关于managed PE文件的注意点: 他们总是使用32PE文件格式, 而不是64PE文件格式. 64位系统上, OS loader检查这个managed 32PE文件并知道如何去创建一个64位地址空间.

9.       至于知识产权保护, 对于所有的编译位IL的代码并且IL代码能被很容易被Disassembler程序reverse, 可以使用一个第三方提供的obfuscator工具. 这些工具scramble” managed module’s metadata中所有private symbols的名称. 另外,可以把一些代码编译为unmanaged DLL并在assembly中调用它.

10.   所有的高级语言都只是提供了CLR的一个功能子集. 但是,IL提供了CLR所有的功能.

11.   如果Assembly中的一个方法第一次被调用,它的IL代码需要被编译为native CPU代码, 这部分功能由CLR’s JIT (just-in-time)完成. JIT编译器在内存中保存了native CPU instructions, 所以当应用程序终止时候,编译的代码都将失效. 另外一个值得记住的重点是JIT编译过程当中有一个专门的优化编译代码的过程.

12.   Microsoft .Net framework提供了一个名为NGen.exe的工具; 这个工具编译一个assembly的全部IL代码为native CPU代码并将结果保存到一个硬盘文件.

13.   IL是一个stack-based的语言, 所有的IL instructions会把operands压栈,并将结果弹出. IL没有提供操作CPU寄存器的指令.


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部

返回版面帖子列表

Microsoft.Net框架程序设计, Part I: Basics of the Microsoft .NET Framework(中文)








签名