以文本方式查看主题 - 曙海教育集团论坛 (http://sun4.cn/bbs/index.asp) -- Microsoft.NET Framework (http://sun4.cn/bbs/list.asp?boardid=78) ---- Microsoft.Net框架程序设计, Part I: Basics of the Microsoft .NET Framework(中文) (http://sun4.cn/bbs/dispbbs.asp?boardid=78&id=2632) |
||||||||||
-- 作者:wangxinxin -- 发布时间:2010-12-15 10:23:04 -- Microsoft.Net框架程序设计, Part I: Basics of the Microsoft .NET Framework(中文) English Version go here.By Alva ChienPart I: Basics of the Microsoft .NET FrameworkChapter 1: The Architecture of the .NET framework Development Platform1. .Net中的common language runtime (CLR) 是一个可以被多个不同语言使用的runtime. 不管使用哪种编译器,所生成的结果都是一个managed module. 一个managed module是一个标准的Windows Portable executable (PE) 文件,这个文件必须由CLR来执行. 一个managed module的组成:
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:
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 header的directory entry 14. (IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR定义在WinNT.h) 如果这个directory entry存在并且拥有一个非0值, OS loader忽略这个文件的导入 (.idata) section并且自动装载MSCorEE.dll到进程的地址空间并直接跳转到对应的函数. 8. 最后一个关于managed PE文件的注意点: 他们总是使用32位PE文件格式, 而不是64位PE文件格式. 在64位系统上, OS loader检查这个managed 32位PE文件并知道如何去创建一个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寄存器的指令. |