__start:
:
init stack;
init heap;
open stdin;
open stdout;
open stderr;
:
push argv;
push argc;
call _main; (调用 main)
:
destory heap;
close stdin;
close stdout;
close stderr;
:
call __exit;
int main(int argc, char *argv[])
// argc:参数个数; argv:参数字符串数组
1. 调用main函数之前,
-
创建进程后,把控制权交给程序的入口函数,即为运行时库的某个入口函数。
-
glibc的入口函数是_start
-
msvc(vc 6.0)的是mainCRTStartup
-
-
入口函数对运行库和运行环境进行初始化,包括堆、I/O、线程、全局变量构造
-
初始化堆,栈(设置栈指针)
-
全局变量、对象和静态变量、对象的空间分配和初始化。
-
初始化C/C++库
-
参数压栈 argc,argv ,获取环境变量
-
打开标准输入,输出、错误流
-
-
注册析构函数,使用atexit注册析构函数(注册时在链表头插入链接,main函数退出也从链表头开始获取链表函数,进行调用)
2. 调用main函数之后,
- 返回入口函数,进行清理工作
- 包括全局变量析构、堆销毁、关闭I/O
-
销毁堆内存
-
关闭标准输入、输出、关闭错误流
-
-
调用exit系统API退出进程
3. 如何在main()函数之前执行一条语句?
(1)在C++中,可通过全局变量的构造函数执行
(2)全局变量的赋值函数
(3)指定入口点,入口点中调用原来的入口点。
4. 用于注册终止函数
- atexit()
int atexit(void (*func)(void))
c库中的atexit()函数,当程序正常中止时,调用指定的func函数。当然,你可以在任何地方注册终止函数,但它会在程序终止的时候被调用。
(终止函数func不接受任何参数)
- _onexit()
4. printf函数是调用stdout指针在屏幕上输出。
#define printf(args...) fprintf(stdout, ##args)
5. 运行时库的主要功能
-
启动与退出,包括入口函数及其依赖函数
-
标准函数
-
I/O,I/O功能的封装和实现,如提供PRINT
-
堆,堆的封装与实现
-
调试支持