1. 入口函数和程序初始化

1.1 程序从main开始吗?

当程序执行到main函数的第一行时,很多事情都已经完成了:

【证1】如下是一段C语言代码:

  • 代码中可以看到,在程序刚刚执行到main的时候,全局变量的初始化过程已经结束了(a的值已经确定);

  • main函数的两个参数(argc 和 argv)也被正确的传了进来;

  • 此外,堆和栈的初始化 已经完成;

  • 一些 系统I/O 也被初始化了,因此,可以放心的使用printf和malloc。

【证2】如下是一段C++ 代码,main之前能够执行的代码还会更多,如下:

在这里,对象v的构造函数,以及用于初始化全局变量g的函数foo都会在main之前调用。

用于初始化全局变量g的函数:

#include <iostream>
using namespace std; int foo()
{
cout << "这个是用来初始化全局变量的函数" << endl;
return ;
} int g = foo(); int main()
{
cout << "这是main函数中第一条语句" << endl; cout << "main函数中直接输出g: " << g << endl; cout << "这是main函数中最后一条语句" << endl; return ;
}

作为全局变量的对象的构造函数:

#include <iostream>    

using namespace std;   

class MyString {
private :
int len;
public:
MyString(int t = ) : len(t) { cout << "默认构造函数" << t << endl; }
int getLen() {
return len;
}
~MyString() { cout << "析构函数调用" << len << endl; } }; MyString t(); int main()
{
cout << "这是主函数里面的第一行语句\n"; MyString a(); cout << "这是主函数里最后一行语句\n"; return ;
}

【证3】atexit:特殊的函数,接收一个函数指针作为参数,并保证在程序正常退出(指从main里返回或调用exit函数时),这个函数指针指向的函数会被调用。如:

  • atexit函数注册的函数的调用时机是在 main结束之后
  • 在main返回之后,它会记录main函数的返回值,调用atexit注册的函数,然后结束进程。

由这些可以看出,首先运行的代码并不是main的第一行,而是某些特别的代码,这些代码负责准备好main函数执行需要的环境。

由此可知,程序的入口点实际上是一个 程序的初始化和结束部分,它往往是库的的一部分。

 

1.2 main函数形式

(1) Linux下常见的main函数形式:

  • int main(int argc, char *argv[])
  • int main(int argc, char **argv)

(2)其他形式:

  • int main()
  • int main(int argc, char **argv, char **envp)

(3) main函数的参数:

  • argc:命令行参数的个数(包括最开始的可执行文件名称)
  • argv:字符指针的数组,每个元素都是一个指向字符串的字符指针,即命令行中的每一个参数;命令行参数的列表,数组长度对应argc
  • envp:字符指针的数组,每一个元素是 指向一个环境变量的字符指针; 它里面存放了当前系统的所有环境变量,环境变量指的是一大组字符串,代表系统开始运行时加载一些东西

3. 分析Linux操作系统如何装载链接并执行程序

尽量描述简单,不讲源码,先看如下的图:

Linux程序加载过程如图:

4. 总结

简短的说,整个在shell中键入./test执行应用程序的过程为:

  • 当前shell进程fork出一个子进程(子shell)

  • 子进程使用execve来脱离和父进程的关系,加载test文件(ELF格式)到内存中。

  • 如果test使用了动态链接库,就需要加载动态链接器(或者叫程序解释器),进一步加载test使用到的动态链接库到内存,并重定位以供test调用。

  • 最后从test的入口地址开始执行test。

Linux下main函数启动过程【程序员自我修养笔记】【自用】的更多相关文章

  1. [oracle] oracle的三种密码验证机制以及在windows和linux下的不同启动过程

    oracle数据库的密码验证机制: ① 操作系统验证 拥有SYSDBA和SYSOPER的用户用该方式验证此时数据库无需启动,也无需开启监听和实例服务. 要求:本地组ora_dba中有该操作系统的登录用 ...

  2. linux编程之main()函数启动过程【转】

    转自:http://blog.csdn.net/gary_ygl/article/details/8506007 1 最简单的程序  1)编辑helloworld程序,$vim helloworld. ...

  3. pwn学习日记Day10 《程序员自我修养》读书笔记

    第一章 从 Hello world 说起 抛出问题: 1.程序为什么要被编译器编译后才能执行? 2.编译器在把C语言程序转换成可以执行的机器码的过程中做了什么,怎么做的? 3.最后编译出来的可执行文件 ...

  4. ***IT程序员自我修养和情商提升文章

    低情商的13个表现 --------------------------------------------------------------------- — THE END —

  5. Linux移植之内核启动过程start_kernel函数简析

    在Linux移植之内核启动过程引导阶段分析中从arch/arm/kernel/head.S开始分析,最后分析到课start_kernel这个C函数,下面就简单分析下这个函数,因为涉及到Linux的内容 ...

  6. 对于linux下system()函数的深度理解(整理)

    原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...

  7. 转:对于linux下system()函数的深度理解(整理)

    这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...

  8. (笔记)Linux下system()函数的深度理解(整理)

    注:从其它地方转的非常好的一篇文章,值得深究! 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数 ...

  9. Linux下使用vim编辑C程序

    这几天在系统能力班自学linux,加上最近大数据课上开始使用linux,我在这里总结一下,linux下使用vim编辑c程序的一些问题. 大数据课上是直接使用micro来编辑的,我这里只是简单的说明一下 ...

随机推荐

  1. 【POJ1083】 Moving Tables (并行的搬运)

    BUPT2017 wintertraining(15) #6E 题意 房间1和2,3和4,...,399和400共用一节走廊,有q次从房间li到ri的搬运桌子,一次搬运10分钟.两个搬运如果走廊有重叠 ...

  2. Android 2019最新面试实战总结

    Android: 今日头条屏幕适配的原理? 1:首先计算出 density,计算公式:当前设备屏幕总宽度(单位为像素)/ 设计图总宽度(单位为 dp) = densitydensity 的意思就是 1 ...

  3. Codeforces | CF1041F 【Ray in the tube】

    昨天晚上全机房集体开\(Div2\),因为人傻挂两次\(B\)题的我开场就\(rank2000+\dots qwq\)于是慌乱之中的我就开始胡乱看题(口胡),于是看了\(F\dots\)(全机房似乎也 ...

  4. ubuntu配置mysql

    1.安装mysql: sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install ...

  5. hexo从零开始

    部署Hexo Hexo官方文档 新建一个文件夹,比如,Blog,然后进入该文件夹下: npm install hexo-cli -g hexo version 安装依赖包 npm install 配置 ...

  6. HDU--5269 ZYB loves Xor I (字典树)

    题目电波: HDU--5269 ZYB loves Xor I 首先我们先解决 ai xor aj 每个数转化为二进制  我们用字典树统计 每个节点 0 和 1 的出现的个数 #include< ...

  7. 把 android 手机变成 web server (golang)

    配置 golang 开发环境 略 安装并初始化 gomobile go get golang.org/x/mobile/cmd/gomobile gomobile init 创建 beego 项目, ...

  8. bzoj2252 矩阵距离

    很好奇这种 普及- 的题为什么会是权限题...... 我一开始想用枚举 + 搜索,看书后发现自己脑抽了.直接BFS即可. #include <cstdio> #include <qu ...

  9. A1130. Infix Expression

    Given a syntax tree (binary), you are supposed to output the corresponding infix expression, with pa ...

  10. luogu2643 聪聪可可

    题目链接 题意 其实转化之后的题意就是求出树上有多少条路径长度是3的倍数.求答案的时候只要将这个数字除以总路径数量就行了. 思路 考虑点分治.对于当前子树,分别求出出树中每个点到根的路径长度对\(3\ ...