程序总是从main函数的第一条语句开始执行的 正确吗?
不对,如下代码:
#include &
static int x = []()
{
std::cout &
输出:
Performs before main function
Performs inside main function
肯定不是从main开始执行的,一个进程启动过程是很复杂的,有些是OS机制决定的(比如ELF载入,动态库载入,和栈结构建立)和语言机制决定的(比如全局对象的构造函数),我下面将Linux启动一个ELF进程的关键过程列出来:
1、可执行文件载入到内存上(Linux kernel干的事情)
2、跳到动态链接器执行(动态链接器干的事情):
2.1:将该可执行文件依赖的动态链接库全部载入到内存上
2.2 : 完成载入动态库的「数据依赖类型」的重定位工作(函数调用类的重定位,一般采用GOT/PLT机制实现延迟绑定,启动过程不做这类的重定位工作)
3、跳到可执行文件的入口地址(entry point) 开始执行(实际上是glibc提供的crtn.o)
3.1 构建执行堆栈
3.2 构建命令行参数和环境变数参数表(即main函数 int main(int argc, char *argv[], char *env[]) 的这几个参数表
3.3 调用可执文件和各动态库的构建函数
4.、跳到main函数执行
只有3.3和4这两步是跟编写的代码相关,之前的步骤都是运行环境相关的事情。上述是关键过程,没有翻代码来写,所以肯定存在错误,还请大家海涵。
有些程序跑的是不带操作系统的,你让它从fuck()开始也行
链接程序可以指定入口,比如ld命令的参数e,后面跟著你指定的入口
脚本语言了解一下
不是,一般会先启动对应语言的运行时。比如你是C++写的就会先启动C++的运行时。
等它完成初始化以后,它再去启动你自己程序的入口点。这个一般是你在编译项目的时候配置的,默认是main函数。当然你也可以指定成别的函数。
实际上不同的系统都有默认的规定。系统在启动你的程序的时候,它会先把你的文件载入到内存离,不管你是Windows还是Linux。完成一系列的初始化操作以后,再去找默认的入口指令去执行。一般而言这个入口指令都是属于运行时的,等它完成初始化以后才会去进入你自己代码的入口。
推荐阅读: