一、      软件执行流程
1、 软件编译流程

Ø  预编译完成宏展开工作。
Ø  为每一个.cxx源文件编译一个目标文件(.obj,.o),目标文件中至少包含二进制的代码段和数据段。在cxx源文件中可能会引用在其他cxx/hxx中定义的符号,也可能是自己定义的一些符号,这些作用域超过一个cxx文件的符号称为“public符号”(例如非静态函数)。因此每一个目标文件中也包含一个符号表,用于记录自己引用的符号及自己提供的public符号。
Ø  编译器合成这些目标文件成一个库文件(.lib),同时解析可以找到的符号引用。此时这个库文件包含了二进制的代码段和数据段,同样也会包含一个符号表,因为有一些符号需要引用其他静态/动态链接库的导出符号。
Ø  链接器负责把目标的库文件和所有需要引用的静态/动态链接库进行链接,即需要首先把静态库合成到可执行文件中。转换相应的符号引用为地址,然后确保所引用的其他动态链接库的符号存在。最后生成可执行文件,可执行文件的符号表只需要记录导入符号表。

2、 软件运行流程

Ø  当双击App.exe图标启动程序时,执行起来的App进程是shell调用CreateProcess激活的。桌面上的带有小箭头的快捷方式(shortcut)就是一个shell链接,shell负责管理一个叫"名字空间"的类似文件系统似的“超文件系统”,它允许应用程序在任何地方在不知访问对象名字和位置的前提下访问到这个对象,此类对象有:文件,目录,驱动器,打印机以及网络资源。而名字空间就是shell把这些对象有层次组织起来的一个结构。名字空间为用户和应用程序提供了一种可靠和高效的方法来访问和管理对象。

Ø  当CreateProcess函数被调用,系统创建一个“进程内核对象”。进程内核对象可以看作一个操作系统用来管理进程的内核对象,它是系统用来存放关于进程统计信息的地方(一个小的数据结构),真正创建者是NtCreateProcess的系统服务函数(也叫执行体服务函数),他创建了进程内核对象供用户扩展。进程内核对象的初始使用计数为1。然后系统为该进程创建4GB(=2^32)的虚拟地址空间(所谓虚拟就不是真的创建4GB的物理内存空间,这些空间不是真在物理内存上).用于加载App.exe可执行文件和任何必要的dll文件的数据和代码。系统为该进程创建4GB的虚拟地址空间,对于windows来说,默认情况下每个用户进程可以占有2GB的私有地址空间;操作系统占有剩余的2GB空间。
    在32位x86系统上:
从0x00000000到0x7fffffff的空间中存放着 应用程序代码,全局变量,每个线程堆栈,dll代码。
从0x80000000到0xc0000000的空间中存放着内核和执行体,HAL(硬件抽象层),引导驱动程序。
从0xc0000000到0xc0800000的空间中存放着进程页表和超空间。
从0xc0800000到0xffffffff的空间中存放着系统高速缓存,分页缓冲池,非分页缓冲池。

Ø  CreateProcess打开应用程序文件(.exe),它先扫描该文件的文件头,该文件头里含有文件能运行在那个环境之下,如果是win32环境,系统就直接加载文件的代码和数据并输入(import)该文件执行所需的dll函数。如果不是win32环境比如是os/2的.exe则先加载相应的环境子系统,再由该环境加载该文件的代码和数据以及该文件执行所需的dll函数。
    加载器负责把可执行文件的数据段和代码段映射到进程的虚拟内存空间中,读入可执行程序的导入符号表,然后根据这些符号表可以查找出该可执行程序所有依赖的动态链接库。

Ø  进程加载代码和数据完毕后,就开始创建线程来执行进程空间内的代码。进程是静态的,它只是线程的容器。一个进程至少因该有一个线程(main thread),其它线程都是主线程通过调用CreateThread函数创建的。线程也是核心对象,他的实际创建者是NtCreateThread系统服务函数。一个线程只是一个线程核心对象和两个堆栈(一个核心堆栈,用于线程运行在核心态;一个用户堆栈,用于线程运行在用户态),线程与进程类似,也拥有线程核心对象计数和线程句柄。线程用于描述进程中的运行路径。
   
Ø  每当进程被初始化时,系统就要创建一个主线程。该线程与c/c++运行时库的启动代码一道开始运行,启动代码则调用进入点函数(就是main函数,它也是主线程的进入点函数),并且继续运行直到进入点函数返回并且c/c++运行时库的启动代码调用ExitProcess为止。每个线程都有自己的入口点函数,主线程入口点函数名字必须是main,wmain,WinMain或wWinMain.而其他的线程入口点函数名字可使用任何名字。每个线程函数必须有一个返回值,它将作为线程的退出代码。对于主线程来说,这个返回值将传给c/c++运行时库的启动函数。c/c++运行时库的启动函数是一个程序调用的第一个函数,它是在程序链接时由链接程序选择相应的启动函数并加到程序的开始处。c/c++运行时库有四个版本的启动函数,他们分别对应不同类型的应用程序。比如,需要ANSI字符和字符串的GUI应用程序的启动函数是WinMainCRTStartup,其对应的进入点函数是WinMain,需要Unicode字符和字符串的GUI应用程序的启动函数是wWinMainCRTStartup,其对应的进入点函数是wWinMain,而需要ANSI字符和字符串的CUI应用程序(如控制台console程序)的应用程序的启动函数是mainCRTStartup,对应的入口点函数为main;需要Unicode字符和字符串的CUI应用程序(如控制台console程序)的应用程序的启动函数为wmainCRTStartup,对应的入口点函数为wmain。c/c++运行时库的启动函数(以WinMainCRTStartup为例)的功能如下:
检索指向新进程的完整命令行指针;检索指向新进程的环境变量的指针;对c/c++运行时的全局变量进行初始化;对c运行期的内存单元分配函数(比如malloc,calloc)和其他低层I/O例程使用的内存栈进行初始化。为C++的全局和静态类调用构造函数。

Ø  启动函数条用主函数,进入应用程序的执行。

Ø  当主函数执行完毕返回时,启动函数就调用c运行期的exit()函数,将返回值(nMainRetVal)传递给启动函数。之后exit()便开始收尾工作。

Ø  运行时启动函数调用操作系统的ExitProcess函数,将nMainRetVal传递给它,这使得操作系统能够撤销进程并设置它的exit 代码。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sshhbb/archive/2011/01/11/6128522.aspx

转载于:https://www.cnblogs.com/shanghe/archive/2011/04/15/2017335.html

程序编译过程与软件启动过程相关推荐

  1. Android程序包管理(1)--PKMS启动过程

    一.PKMS启动过程 1.重要文件目录介绍 1.目录: /system/ect/permissions/xxx.xml:加载系统feature /system/ect/permissions/plat ...

  2. Android系统默认Home应用程序(Launcher)的启动过程源代码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  3. Android系统默认Home应用程序(Launcher)的启动过程源代码分析(3)

    Step 13.  ActivityStack.startActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/ ...

  4. Android应用程序组件Content Provider的启动过程源代码分析(1)

             通过前面的学习,我们知道在Android系统中,Content Provider可以为不同的应用程序访问相同的数据提供统一的入口.Content Provider一般是运行在独立的进 ...

  5. 用英语简述计算机的启动过程,计算机的启动过程(详细)

    对于使用电脑用户来说,打开电源启动电脑几乎是每天必做的事情,但计算机在显示这些启动画面的时候都在做什么呢?大多数用户都未必清楚. 下面就向大家介绍一下从打开电源到出现Windows桌面的蓝天白云,计算 ...

  6. 传统的BIOS启动过程与UEFI启动过程

    1.传统的BIOS启动过程 开机--BIOS初始化--BIOS自检--引导操作系统--进入系统 2.UEFI启动过程 开机--UEFI初始化--引导操作系统--进入系统(省了自检这一步,开机速度稍微快 ...

  7. 改造独立部署(SCD)模式下.NET Core应用程序 dotnet的exe文件启动过程

    设置一个小目标 改造前 改造后 独立部署SCD模式,是指在使用dotnet publish 命令时带上-r 参数运行时标识符(RID). 目标提出原因:SCD模式下文件太乱了,很多文件在开发时大多又涉 ...

  8. 程序员之常用软件安装过程记录

    前言 最近重做系统,顺便整理一下安装常见编程语言和工具过程 本文原创,创作不易,转载请注明!!! Work 这部分主要是开发工具和编程环境的安装与测试运行 C/C++ CodeBlocks 安装与调试 ...

  9. Android系统默认Home应用程序(Launcher)的启动过程源代码分析(2)

    Step 10.  ActivityManagerService.systemReady 这个函数是在上面的Step 6中的ServerThread.run函数在将系统中的一系列服务都初始化完毕之后才 ...

最新文章

  1. matlab神经网络 时间序列,请问吧里有大神做过MATLAB时间序列神经网络(NARX)吗?...
  2. Node.js Web 模块
  3. Qt修炼手册4_信号与槽
  4. Linux使用locate命令查找,Linux如何使用locate命令查找数据(2)
  5. ffmpeg结构体SpecifierOpt说明文档
  6. AcWing1075. 数字转换(树形DP)题解
  7. ARTS打卡第14周
  8. cmake中添加引用动态链接_C和C++使用对方编译的动态链接库
  9. 最强内存稳定性测试软件,内存稳定性测试软件Memtest正式版——HyperX FURY DDR4成绩喜人...
  10. cms自动更新php文件,PHPCMS站群管理系统-PHPCMS自动采集-PHPCMS自动更新
  11. 记录mikrotik路由器的折腾过程
  12. SCARA四轴机器人丝杆花键_视频图文为你揭秘SCARA机器人!马了备用!
  13. 推荐几个长期有效的免费服务器和免费vps游戏服务器亲测再用
  14. Android项目实战--手机卫士34--流量管理
  15. 随机游走 推荐系统论文阅读
  16. Linux多线程服务端编程学习(四)finger服务的实现
  17. js 中日期 转换成时间戳 例如2013-08-30 转换为时间戳
  18. ClickHouse MergeTree表引擎和建表语句
  19. 科普——未知的公共免费WIFI存在的风险及隐患
  20. Angr 操作栈的符号执行 04_angr_symbolic_stack

热门文章

  1. [python]python logging 模块
  2. Codeforces Round #533 (Div. 2) 部分题解A~D
  3. MyEclipse6.5的反编译插件的安装
  4. 为什么前端H5工程师工资那么高?
  5. 信号(signal)
  6. cocos2d-X   CCSprite设置贴图(图片)大小
  7. 学者CIO邓遵红:让人文梦想照进职业现实
  8. 前端调用mysql异步_python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据...
  9. 【数据结构】二叉树的python实现
  10. 集成学习的前世今生(一)