您的位置:首页 > 其它

托管模块结构及运行机制

2007-08-25 16:33 357 查看
托管文件模块组成

PE表头: 文件类型:(GUI,CUI,DLL),时间标记(文件创建时间)

.text部分:包含JMP _CorExeMain指令

.idata部分,保护MSCorEE.dll引用

CLR表头: 包含托管模块信息:CLR版本号,Main方法的MethodDef元数据标记,托管模块的元数据,资源,强命名,标记信息的位置和尺寸

元数据: 包括元数据表,有两种,一种描述源代码中定义的类型和成员,一种描述源代码中应用的类型和成员

中间语言:编译器编译代码时产生的指令。

清单(manifest)

元数据构成:

元数据是一块二进制数据,包含一些表

定义表:

1. ModuleDef: 包括托管模块的条目,条目主要包括模块的文件名,扩展名等

2. TypeDef:托管代码定义的每一个类型都在TypeDef中一个对应条目,包括类型的名称,基类型,类似public访问标记,以及一些指针(指针指向MethodDef表中该类型的方法,FieldDef中该类型的字段以及PropertyDef和EventDef表中属于该类型的成员)

3. MethodDef:托管模块中定义的每个方法在MethodDef中都对应一个条目,包括方法名,访问标记,方法签名,已经该方法的IL代码在模块中的偏移量,还包括一个指向ParamDef的指针

4. FieldDef:

5. ParamDef:

6. PropertyDef:

7. EventDef:

引用表:

1. AssemblyRef:托管模块中每一个引用在AssemblyRef中都有一个对应条目,记录程序集名称,版本,语言文化以及一个公有密钥标记

2. ModuleRef:用来记录实现在同一程序集中的其它不同模块的一些类型

3. TypeRef:

4. MemberRef:

清单表:

1. AssemblyDef:

2. FileDef:

3. ManifestResourceDef:

4. ExportedTypesDef:

程序集执行:

编译期:

1. 编译器编译程序时,再PE文件的.text部分嵌入指令 JMP _CorExeMain

2. _CorExeMain函数存在MSCorEE.dll中,所以MSCorEE.dll将在PE文件的.idata部分被引用

执行期:

1. Windows加载该PE文集

2. 发现其.idata部分存在MSCorEE.dll引用,于是加载MSCorEE.dll,获取_CorExeMain函数地址,用此地址修正JMP指令。

3. 进程开始执行修正后的JMP指令, 该指令跳转倒MSCorEE.dll中的_CorExeMain函数,此函数初始化CLR, 然后此函数查看CLR表头的Main函数位置。

4. 找到Main函数后,PE文件的IL被JIT编译成CPU指令。

5. CLR跳转到编译后的指令,程序开始运行。

托管方法的调用:

1. 方法执行之前,CLR会检查方法中引用到的所有类型。

2. CLR为方法分配一个内部数据结构,用于管理所有引用类型。该方法引用到的所有类都会被分配,该类中的每个方法都有一个对应的条目,每个条目都将被初始化为一个没有记录的函数(JITCompiler函数)

3. 当调用到该条目的时候,JITCompiler被调用,其搜索元数据,找到IL位置其将验证IL并编译为CPU指令(即所谓的及时编译JIT)

4. JITCompiler用CPU指令的位置替换该调用方法的地址

5. JITCompiler跳转到该内存代码上开始执行

6.如果第二次调用将直接使用该方法的地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐