不对,如下代码:

#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。完成一系列的初始化操作以后,再去找默认的入口指令去执行。一般而言这个入口指令都是属于运行时的,等它完成初始化以后才会去进入你自己代码的入口。


推荐阅读:
相关文章