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

2023-11-09

很是受益。。。

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

 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++运行时库的一点理解,若有错漏,欢迎指正。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • fopen_s 怎么会比 fopen 更安全呢?

    我正在处理遗留代码Windows平台 当我编译代码时VS2013 它给出以下警告 错误 C4996 fopen 该函数或变量可能不安全 考虑使用fopen s反而 要禁用弃用 请使用 CRT SECURE NO WARNINGS 详情请参见
  • ASP.NET Web 应用程序中的身份验证遇到问题

    我正在尝试对从登录页面登录我的 Web 应用程序的用户进行身份验证 我正在使用本教程 http support microsoft com kb 301240作为指南 它几乎准确地解释了我希望做什么 但是当我输入用户名和密码时 验证不起作用
  • .crt 部分?这个警告是什么意思?

    我最近收到此警告 VC 2010 warning LNK4210 CRT section exists there may be unhandled static initializers or terminators 我假设这是关键部分
  • 平滑手绘曲线

    我有一个允许用户绘制曲线的程序 但这些曲线看起来不太好 它们看起来摇摇欲坠 而且是手绘的 所以我想要一种能够自动平滑它们的算法 我知道平滑过程中存在固有的模糊性 因此它不会每次都完美 但这种算法似乎确实存在于多个绘图包中 并且它们工作得很好
  • 使用 C# 将多个音频样本混合到单个文件中

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个能够创建音频文件 mp3 或 wav 的库 NAudio http www codeple
  • 如何从 Qt 应用程序通过 ODBC 连接到 MySQL 数据库?

    我有一个新安装的 MySQL 服务器 它监听 localhost 3306 从 Qt 应用程序连接到它的正确方法是什么 原来我需要将MySQL添加到ODBC数据源 我在遵循这个视频教程后做到了这一点 https youtu be K3GZi
  • 如何在C中同时运行两个子进程?

    所以我开始学习并发编程 但由于某种原因我什至无法掌握基础知识 我有一个名为 fork c 的文件 其中包含一个 main 方法 在此方法中 我将 main 分叉两次 分别进入子进程 1 和 2 在孩子 1 中 我打印了字符 A 50 次 在
  • Linq 合并列表

    我的课 public class Foo public int A get set public List
  • 控制台应用程序中使用 Unicode 字符的 _tprintf

    我正在从 Unicode 构建的控制台应用程序 使用 C 和 Visual Studio 2008 执行这个简单的输出 此代码旨在在 Windows 上运行 tprintf L Some sample string n 一切正常 但是如果我
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 处理“未找到细胞”。 Excel 中的错误

    我正在使用 Excel VSTO 应用程序并使用以下代码在工作表中查找错误单元格 Excel Range rngTemp Excel Range rngErrorRange Excel Worksheet Sheet1 Excel Work
  • 如何从外语线程调用Python函数(C++)

    我正在开发一个程序 使用 DirectShow 来抓取音频数据 媒体文件 DirectShow 使用线程将音频数据传递给回调 我的程序中的函数 然后我让该回调函数调用另一个函数 Python 中的函数 我使用 Boost Python 来包
  • 如何构建一棵与或树?

    我需要一个支持 与 和 或 的树结构 例如 给定一个正则表达式 如ab c d e 我想把它变成一棵树 所以 一开始我们有两个 或 分支 它可以向下ab or c d e 如果你低头ab分支 你得到两个节点 a and b or a其次是b
  • C#:自定义转换为值类型

    是否可以将自定义类转换为值类型 这是一个例子 var x new Foo var y int x Does not compile 是否有可能实现上述情况 我需要超载一些东西吗Foo 您将必须重载强制转换运算符 public class F
  • Type.GetInterfaces() 仅适用于声明的接口

    首先 像这样的问题有很多 也许有些OP甚至在问同样的问题 问题是这些问题的答案 无论是否接受 都没有真正回答这个问题 至少我找不到 如何确定类直接声明的接口 而不是由父级或声明的接口继承的接口 e g interface I interfa
  • 连接到没有元数据的网络服务

    我想连接到此网络服务 https training api temando com schema 2009 06 server wsdl https training api temando com schema 2009 06 serve
  • 如何将System.Windows dll添加到Visual Studio 2010 Express?

    我正在开发一个小型应用程序C and VS2010 as IDE with NET框架4 我想用CaptureSource类以便从笔记本电脑的网络摄像头捕获视频 为此我需要添加一个命名空间System Windows DependencyO
  • Boost.asio和异步链,unique_ptr?

    我对异步编程不太熟悉 我有一个问题 我的问题如下 给出 boost asio 中 C 11 的 echo server 示例 http www boost org doc libs 1 60 0 doc html boost asio ex
  • 如何在c#中创建多线程

    我需要监听机器中的所有串行端口 假设我的机器有 4 个串行端口 我必须创建 4 个线程并开始分别使用附加线程监听每个端口 我使用此代码来获取我的机器中的端口数量 private SerialPort comPort new SerialPo
  • 将一个 IEnumerable 拆分为多个 IEnumerable

    我是 linq 新手 我需要根据指示器将 Couple string text bool Indicator 类型的 IEnumerable 拆分为多个 IEnumerable 我尝试使用skipWhile 和 TakeWhile 但没有找

随机推荐

  • Native memory allocation (mmap) failed to map 6215958528 bytes for committing reserved memory

    今天突然发现es报错 无法正常启动 报错信息如下 Exception in thread main java lang RuntimeException starting java failed with 1 output There is
  • 【微信小程序入门到精通】— 渲染列表的详细方法

    目录 前言 一 引入 wx for 1 1 wx for 语法结构 1 2 wx for 实例 二 wx key 应用 总结 前言 对于目前形式 微信小程序是一个热门 那么我们该如何去学习并且掌握之后去做实际项目呢 为此我特意开设此专栏 在
  • CVE-2021-3493漏洞复现案例(提权)

    下面复现需要在虚拟机中完成 CVE 2021 3493漏洞案例 可以在下面链接下载关于该漏洞的代码脚本 https github com inspiringz CVE 2021 3493 1 攻击工具及环境说明 在虚拟机上完成 Ubuntu
  • 【已更新】2023mothercup妈妈杯D题数学建模挑战赛思路代码-航空安全风险分析和飞行技术评估问题

    我们来看下D题 这道题是一道数据分析类题目 总共有五个小问 第一题是要求我们针对附件1的数据质量开展可靠性研究 提取与飞行安全相关的部分关键数据项 并对数据项的重要程度进行分析 第一步是对数据的可靠性分析 数据质量的可靠性研究主要包括数据完
  • win32 socket编程 示例(功能简单,完善)

    最近在做的一个项目要用到网络通信方面的内容 于是自学了下win32socket 原来自己学过计算机网络 只了解网络各层的原理 但没有真正的编程来实现这些原理 哎 不过现在还来得及 下面是自己的一个示例 虽然简单 但了解了它 就知道了最基本的
  • Idea 学生认证

    Idea 学生认证 具体步骤 认证地址 操作如图 具体步骤 认证地址 https www jetbrains com community education students 操作如图 学生邮箱会收到来信 认证完成
  • linux常用命令笔记(二)

    2020 03 18 一 echo 1 原文输出 双引号可加可不加 echo hello world echo hello world 2 输出变量的值 echo 变量名 echo PATH 输出环境变量PATH的值 注意 linux环境变
  • 每一代内存的读写速度大概是多少?

    每一代内存的读写速度大概是多少 原文 https zhidao baidu com question 1797460631148535467 html 内存 有核心频率 I O频率 等效频率 最后由等效频率而算出带宽 带宽就等于内存的速度
  • vite+react+ts+eslint+prettier构建react开发项目

    目录 一 构建项目 二 安装eslint和prettier的依赖 三 修改 eslintrc cjs 创建 prettierrc cjs 1 eslintrc cjs文件配置 2 prettierrc cjs文件配置 三 将错误显示在页面上
  • 蓝桥杯嵌入式CT117E-M4学习笔记08-串口通信实验

    文章目录 前言 一 实验原理 二 配置步骤 三 串口发送 1 直接使用HAL USART Transmit发送 2 使用重定向prtinf函数发送 四 串口接收 总结 前言 本节我们学习开发板的串口通信 一 实验原理 1 串口通信原理 详见
  • 浏览器的渲染机制、提升页面性能、错误监控上报

    js运行机制 微任务队列 事件循环 单线程 错误监控 CSRF防范 css盒模型 Dom事件 原型链
  • 接口测试工具-apipost

    apiost Postman Swagger Mock 功能特色 实现多人实时协作 接口自动化测试 选择接口 组成流程 执行流程 基于接口创建在线文档可分享 官网 Apipost API 文档 调试 Mock 测试一体化协作平台 API列表
  • 02.07_两个链表相交

    给你两个单链表的头节点 headA 和 headB 请你找出并返回两个单链表相交的起始节点 如果两个链表没有交点 返回 null 解法一 如果两个链表有相交 那么从后面看一定是相同的 所以只需要把长的移动到和短的链表一样的长度开始遍历即可
  • 低成本副业:开发小程序商城攻略

    随着互联网的普及和电子商务的兴起 越来越多的人选择做点副业 其中开发小程序商城是一个不错的选择 相比传统的实体店 小程序商城的成本更低 而且门槛更低 可以让更多的人参与到副业中来 那么 如何开发自己的小程序商城呢 下面为大家介绍步骤和技巧
  • STM32中遇到的问题--关于串口的一些常见问题

    在单片机的开发过程中 最常用的外设就是串口了 是用来进行bug纠错 log输出的常用工具 也是用来与外部通讯的常见协议之一 但是在使用串口的过程中难免会遇到一些问题 下面就我在工作遇到的一些问题做了一些记录 与大家分享 其实也是为了自己在以
  • [云原生专题-39]:K8S - 核心概念 - 存储抽象- pod配置文件的挂载ConfigMap

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122856681 目录 前言 第1章
  • 安卓逆向入门指南:应用分析与反编译

    安卓逆向入门指南 应用分析与反编译 概述 简要介绍安卓逆向工程的基本概念和背景 解释逆向工程的目的和重要性 以及在安全审计和应用研究中的应用 应用分析 安卓应用文件结构的解析 介绍APK文件的结构 包括AndroidManifest xml
  • c#中new 后面大括号

    C new一个对象的时候 后面的参数不是用小括号吗 下面的大括号是怎么回事 不是数据为什么会用大括号 BarcodeWriter barcodeWriter new BarcodeWriter Format ZXing BarcodeFor
  • jmap、jstat、jinfo、jstack命令详解

    jmap jmap histo pid gt log txt 此命令可以用来查看内存信息 实例个数以及占用内存大小 num 序号 instances 实例数量 bytes 占用空间大小 class name 类名称 C is a char
  • Windows中.exe程序的启动过程和C/C++运行时库<转载>

    很是受益 Windows中 exe程序的启动过程和C C 运行时库 lt 转载 gt Windows系统中 exe后缀的文件一般可以双击运行 编程时 编译出来的最终结果一般也表现为一个exe程序和其他的为程序执行提供支持的dll 我们双击一