Windows中.exe程序的启动过程和C/C++运行时库

转载 2012年03月26日 09:25:49
Windows系统中,.exe后缀的文件一般可以双击运行。编程时,编译出来的最终结果一般也表现为一个exe程序和其他的为程序执行提供支持的dll。我们双击一个exe程序的时候,在操作系统层面上,做了些什么使得应用程序能够执行呢?

现在有一个App.exe文件,根据这篇文章的说法,我总结了一下,双击App.exe之后操作系统做的工作如下:

1、 shell调用CreateProcss激活一个App.exe进程。Shell即命令解释器,是操作系统引导时即加载的一个系统进程,在Windows任务管理器里面可以看到一个名为”Explorer.exe”的进程,就是它了。

2、 CreateProcss创建了一个进程内核对象,而系统为该进程创建4GB的虚拟地址空间(在Win2000/WinXP下,每个进程可以有2GB的私有地址空间,剩余的2GB由操作系统占用)用来加载App.exe和其他必要的DLL函数;

3、 CreateProcess加载exe文件,分析文件头(具体格式见PE文件格式分析)以识别文件的运行环境,根据文件头决定由那个环境进行加载操作;

4、 加载App.exe及其必要的DLL文件数据和代码后,CreateProcss即创建主线程,执行C/C++运行时的启动代码,由启动代码执行剩下的过程。


从上面的描述可以看出,一个程序真正调用的第一个应该是C/C++运行时的启动函数。那么C/C++运行时库在程序运行时起到了什么样的作用?下面是关于C/C++运行时的一些学习体会。

什么是C/C++运行时库,网上随便一搜,能得到一大串结果。运行时库是一个library,我们日常编写的程序代码都是运行在这个库上的,运行时库完成了一些底层的基础的工作,例如初始化运行期间的内存单元分配函数,初始化底层I/O例程使用的内存栈,初始化C/C++运行时的全局变量,为C++全局和静态类调用构造函数等等。这样的运行时库使得程序员不必关心过于底层的内容,专注于自己的应用程序逻辑。运行时库还提供一些基础的库函数调用,如memcpy,malloc之类的,更重要的是,运行时库还为应用程序添加启动函数。

Windows环境下,VC提供的 C run-time library又分为动态运行时库和静态运行时库。动态运行时库主要是msvcrt.dll(Debug版:msvcrtd.dll),对应的库文件是msvcrt.lib(Debug版:msvcrtd.lib)。静态运行时库对应的主要文件是:libc.lib (单线程静态库)和libcmt.lib (多线程静态库)。其中msvcrt.dll提供几千个C函数,包括printf这么低级的函数也在msvcrt.dll中。

应用程序编写完成后进行编译和链接时,编译器根据编译选项(Visual Studio中即为工程设置),如单线程、多线程或DLL,自动为应用程序链接不同的运行时库的启动函数。在VS2005中,通过下面的操作可以查看或修改选项以决定链接哪个运行时库:

打开工程属性,选择左侧的配置属性—->C/C++—->代码生成,查看【运行时库】,选择不同的运行时库即可。

回到第一个问题,主线程执行C/C++运行时的启动代码,由启动函数调用对应的入口点函数,进入应用程序执行代码逻辑。

不使用宽字节的控制台程序的启动函数为mainCRTStartup。这个函数在VC安装目录下的crt\src\ crt0.c文件中。下面是一个从网上找到的简化版:

void mainCRTStartup(void)

{

int mainret;

/*获得WIN32完整的版本信息*/

_osver = GetVersion();

_winminor = ( _osver >> 8 ) & 0×00FF ;

_winmajor = _osver & 0×00FF ;

_winver = ( _winmajor << 8 ) + _winminor;

_osver = ( _osver >> 16 ) & 0×00FFFF ;

_ioinit(); /* initialize lowio */

/* 获得命令行信息 */

_acmdln = (char *) GetCommandLineA();

/* 获得环境信息 */

_aenvptr = (char *) __crtGetEnvironmentStringsA();

_setargv(); /* 设置命令行参数 */

_setenvp(); /* 设置环境参数 */

_cinit(); /* C数据初始化:全局变量初始化,就在这里!*/

__initenv = _environ;

mainret = main( __argc, __argv, _environ ); /*调用main函数*/

exit( mainret );

}

从以上代码可知,运行库在调用用户程序的main或WinMain函数之前,进行了一些初始化工作。初始化完成后,接着才调用了我们自己编写的main或WinMain函数。这样, C/C++运行时库和应用程序就正常地工作起来了。

除了crt0.c外,C运行时库中还包含wcrt0.c、 wincrt0.c、wwincrt0.c三个文件用来提供初始化函数。wcrt0.c是crt0.c的宽字符集版,wincrt0.c中包含 windows应用程序的入口函数,而wwincrt0.c则是wincrt0.c的宽字符集版。

同样由上面简化版的代码可知,当用户程序的main或WinMain函数执行结束后,返回值被当做参数传入exit函数中,有exit完成程序执行的收尾工作,包括析构C++全局和静态类,调用操作系统的ExitProcess函数,告知进程退出等。

以上是我对于程序执行过程和C/C++运行时库的一点理解,若有错漏,欢迎指正。

windows C/C++ 在一个程序中打开,关闭和监视其它的exe程序

本文要实现的功能就是在windows下,实现用一个程序来打开,关闭和监视其它的exe程序,我这里的的exe程序是我自己实现的。 1.监视exe是否崩溃 首先如果一个进程不在了,它的进程ID就是0, 那...
  • lumanman_
  • lumanman_
  • 2017年06月08日 15:57
  • 1570

Windows系统开机自动运行程序和自动启动服务

[转] http://blog.sina.com.cn/s/blog_54cae6d70100gkws.html 一、经典的启动——“启动”文件夹 单击“开始→程序”,你会发现一个“启动”菜单,这...
  • liangzhao_jay
  • liangzhao_jay
  • 2013年11月27日 16:23
  • 2919

如何实现程序的重新启动(windows环境下)

背景: 在游戏程序的开发中,经常会碰到这样的情况,运行游戏更新程序后需要重新启动更新程序,在游戏内修改视频等相关设置后需要重新启动游戏程序,这样的操作该如何实现呢? 解决方案: 一种解决方案是通过...
  • u010832643
  • u010832643
  • 2014年10月22日 09:39
  • 4189

Windows中.exe程序的启动过程和C/C++运行时库<转载>

很是受益。。。 Windows中.exe程序的启动过程和C/C++运行时库  Windows系统中,.exe后缀的文件一般可以双击运行。编程时,编译出来的最终结果一般也表现...
  • anhuidelinger
  • anhuidelinger
  • 2013年10月29日 20:05
  • 951

Windows环境下exe、lib、dll文件怎么确定自己选择哪个版本c运行时库的

Windows环境下,c运行时库mscrt.dll,会有多个版本。 Run-Time Library是编译器提供的标准库,提供一些基本的库函数和系统调用。我们一般使用的Run-Time Librar...
  • mofabang
  • mofabang
  • 2015年11月02日 09:03
  • 1122

windows的exe、lib文件跟c运行时库怎么关联的

2015-11-2 09:22:02 Am Monday 嗨,周一。一个新的工作周的开始。在Windows操作系统下,可执行文件的存储格式是PE(Portable Executable)格式的;在L...
  • mofabang
  • mofabang
  • 2015年11月02日 11:34
  • 835

C/C++运行时库到底在Windows中起什么作用(猜想)

以下是作者的一些猜想:   1. 我们在用VC编程时,会在执行我们的main函数前,系统先通过Kernel32调用一些函数,执行一些C的初始化准备工作,我们一般叫C运行时库的初始化。那么这些初始化...
  • gmxydm
  • gmxydm
  • 2013年08月18日 13:36
  • 950

C/C++运行时库 解释

I. CRT CRT(C/C++ Runtime Library)是支持C/C++运行的一系列函数和代码的总称。虽然没有一个很精确的定义,但是可以知道,你的main就是它负责调用的,你平时调用的诸如...
  • shixin_0125
  • shixin_0125
  • 2015年03月27日 11:06
  • 662

main函数执行之前都干啥了----C/C++运行时库剖析

本文介绍运行时库实现的功能,你会看到在main函数执行之前都做了什么操作!...
  • yueqian_scut
  • yueqian_scut
  • 2014年04月23日 23:03
  • 2537

关于C\C++运行时库的多线程版本的工作记录

关于C\C++运行时库的多线程版本的工作记录 http://www.cnblogs.com/dawen/archive/2011/05/18/2050299.html 这段时间在做...
  • dongfengkuayue
  • dongfengkuayue
  • 2015年07月24日 14:10
  • 408
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Windows中.exe程序的启动过程和C/C++运行时库
举报原因:
原因补充:

(最多只允许输入30个字)