写了那么多C#代码,大家有没有想过自己写的代码编译后的可执行文件内部是什么样子,是怎样在系统上运行的?

编译成exe,然后双击exe文件运行,这中间到底发生了些什么呢,这篇先来剖析下exe内部的样子:

我们知道C#代码编译后的结果是IL(Intermediate Language),那生成的exe文件里面都是IL吗,当然不会。

C#生成的exe既然是window下可执行文件,那也就是标准的PE文件,和普通win32的exe文件格式一样。我们来看下exe文件的格式:

dll文件本质上和exe一样,只是少了入口函数。

MS-DOC MZ Header和MS-DOS Stub是为了兼容DOS系统存在的,目的是使这个exe在DOS下执行时弹出一个提示"This program cannot be run in DOS mode"。

PE Header包含了这个文件的一些信息,如:文件创建日期,文件类型,Section的数量,Optional Header的大小等等。详细可以参考Winnt.h里的结构_IMAGE_FILE_HEADER。

PE Optional Header则包含了文件的版本号以及重要的基地址和AddressOfEntryPoint(RVA-Relative Virtual Address),这是程序执行的入口地址,双击exe后就从这里开始执行。对C#程序来说,这里指向的是.net的核心库MsCorEE.dll的_CorExeMain()函数。当然这是针对XP系统的,XP以后的系统,OS Loader已经可以判断出这个PE是否包含CLR头来决定是否运行MsCorEE.dll的_CorExeMain()函数。

Section有很多,包括代码节,数据节等,C#程序会把CLR头,元数据,IL放在这里面。

CLR是什么呢,全称Common Language Runtime,公共语言运行时,CLR主要是管理程序集,托管堆内存,异常处理和线程同步等等。

CLR头具体可以参考CorHdr.h中的IMAGE_COR20_HEADER结构,如下:

 typedef struct IMAGE_COR20_HEADER
{
// CLR版本信息
ULONG cb;
USHORT MajorRuntimeVersion;
USHORT MinorRuntimeVersion; IMAGE_DATA_DIRECTORY MetaData; //元数据
ULONG Flags;
ULONG EntryPointToken; //入口函数Main的标识 IMAGE_DATA_DIRECTORY Resources; //资源
IMAGE_DATA_DIRECTORY StrongNameSignature; //强名称标识 // Regular fixup and binding information
IMAGE_DATA_DIRECTORY CodeManagerTable;
IMAGE_DATA_DIRECTORY VTableFixups;
IMAGE_DATA_DIRECTORY ExportAddressTableJumps; // Precompiled image info (internal use only - set to zero)
IMAGE_DATA_DIRECTORY ManagedNativeHeader; }
IMAGE_COR20_HEADER;

元数据很重要,验证代码类型安全,GC的对象引用跟踪还有我们常用的反射都需要用到元数据。

元数据主要由定义表,引用表,清单表组成。

定义表包括应用所有的类型,方法,字段,属性,参数,事件的定义,代码里任何的定义项都可以在这个表里找到,反射就是靠这个表只要一个名字就能得到属性或函数。运行时的类型安全检查也离不开它。

引用表包括程序集,类型和成员的引用,我们知道GC在回收内存时先默认认为所有对象都是垃圾,然后通过线程栈上的根(cpu寄存器,局部变量,参数,静态变量)找引用的对象,能找到的说明还在使用就去掉垃圾标记,这个表可以让GC在回收内存时方便从根找到所有引用。

清单表主要是程序集,文件,资源的定义。

IL就不多说了,不了解的朋友可以参考小弟的另一篇文章:30分钟?不需要,轻松读懂IL

元数据和IL都可以通过工具ildasm.exe来查看。

以上就是C#生成的exe文件的主要结构,下篇再讲exe文件的运行过程,谢谢。

你的C#代码是怎么跑起来的(一)的更多相关文章

  1. 你的C#代码是怎么跑起来的(二)

    接上篇:你的C#代码是怎么跑起来的(一) 通过上篇文章知道了EXE文件的结构,现在来看看双击后是怎样运行的: 双击文件后OS Loader加载PE文件并解析,在PE Optional Header里找 ...

  2. CLR via C#(01)-.NET平台下代码是怎么跑起来的

    1. 源代码编译为托管模块 程序在.NET框架下运行,首先要将源代码编译为托管模块.CLR是一个可以被多种语言所使用的运行时,它的很多特性可以用于所有面向它的开发语言.微软开发了多种语言的编译器,编译 ...

  3. 你编写的Java代码是咋跑起来的?

    如果你是一名 Java 开发人员,你肯定指定 Java 代码有很多种不同的运行方式.比如说可以在开发工具(IDEA.Eclipse等)中运行,可以双击执行 jar 文件运行,也可以在命令行中运行,甚至 ...

  4. PyODPS DataFrame 的代码在哪里跑

    在使用 PyODPS DataFrame 编写数据应用时,尽管编写的是同一个脚本文件,但其中的代码会在不同位置执行,这可能导致一些无法预期的问题,本文介绍当出现相关问题时,如何确定代码在何处执行,以及 ...

  5. VSCode代码修改后跑起来没反应,打开本地文件,代码没变化

    两种解决办法: 首先:修改VSCode默认配置文件,点击左下角设置标志图 -> 设置,出来了设置相关的东西,搜索 files.autoSave 第一种:把"files.autoSave ...

  6. 只有20行Javascript代码!手把手教你写一个页面模板引擎

    http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...

  7. vim下使用YouCompleteMe实现代码提示、补全以及跳转设置

    配置YouCompleteMe 1. 安装vundle vundle是一个管理vim插件的工具,使用vundle安装YouCompleteMe比较方便. 按照作者在https://github.com ...

  8. 【Android】TextView跑马灯效果

    老规矩,先上图看效果. 说明 TextView的跑马灯效果也就是指当你只想让TextView单行显示,可是文本内容却又超过一行时,自动从左往右慢慢滑动显示的效果就叫跑马灯效果. 其实,TextView ...

  9. C# 13行代码带你模拟登录QQ空间

    最近想做一个QQ空间点赞的小工具,于是晚上下班回来就开始分析PC版的QQ空间,打开Chrome,切换到Network,然后输入账号密码,然后点击登录... 然后,我曹....一堆请求就开始了....搞 ...

随机推荐

  1. 存储过程之七—java代码调用

    一.简介 jdbc调用存储过程与调用一般的sql语句有些差别.jdbc调用一般的sql语句的时候,返回的是结果集,或是sql语句后是否执行成功的标记量.而存储过程返回的可以是结果集,输出参数.返回状态 ...

  2. maven 仓库搜索添加需要的jar包

    可用仓库网址: http://search.maven.org/#browse http://mvnrepository.com/ http://repository.sonatype.org/ind ...

  3. Eclipse中使用Git-让版本管理更简单

    详细步骤: 第一部分  GIT介绍 (1)GIT往世今生 2005年开发Samba的Andrew试图破解BitKeeper(一款商业的版本控制系统)的协议(这么干的其实也不只他一个),被BitMove ...

  4. 动态规划--模板--hdu 1059 Dividing

    Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  5. 详解Webwork中Action 调用的方法

    详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultAction ...

  6. 如何在ZBrush中添加毛发

    ZBrush不仅能雕刻出完美的头发造型,还能够应用真实的头发和毛发.在制作毛发之前只需要简单定义遮罩区域,包括长短.疏密.当然,最重要的是,你可以使用Polypaint生成各种有色纤维,这将非常方便. ...

  7. codeforces 712B B. Memory and Trident(水题)

    题目链接: B. Memory and Trident time limit per test 2 seconds memory limit per test 256 megabytes input ...

  8. CSS select样式优化 含jquery代码

    CSS 下拉选择菜单基本的CSS样式不怎么好看,通过一些简单的样式优化,可以得到如下图这样的: html结构如下: <div class="sel_wrap"> < ...

  9. HDU 5033 Building --离线+单调栈

    题意:给一些建筑物,x表示横坐标,h表示高度,然后查询某些坐标x,问从该点看向天空的最大张角是多大. 解法:离线操作,读入所有数据,然后按x升序排序,对每一个查询的x,先从左到右,依次添加x坐标小于x ...

  10. 二分匹配之最大权值匹配算法---KM模板

    百科:http://baike.baidu.com/link?url=vbM3H4XmfrsWfP-epdlR2sVKSNzOq4hXnWDqm5uo8fd7VWsF2SmhDV35XyVUDvVjv ...