程序入口函数与初始化
2015-10-19 23:02
246 查看
1.概述程序执行过程:
1)操作系统在创建进程后,将控制权交给了程序的入口,这个入口通常是运行库的某个入口函数2)入口函数对运行库和程序运行环境进行初始化,包括堆,IO,线程,全局变量的构成
3)入口函数完成初始化后,调用 main 函数,正式执行程序主题
4)main函数执行完毕后,返回到入口函数,入口函数进行清理,包括全局变量析构,堆销毁,关闭I/O等,然后进行系统调用结束进程。
2.linux 中 glibc入口函数
1)操作系统将控制权交给进程入口,_start 函数,由汇编实现,与平台相关,以下代码仅供参考:_start: xorl %ebp,%ebp //将寄存器 ebp 清零 popl %esi // 弹出 argc,将其存放在 esi 中 movl %esp,%ecp // 使寄存器 ecp 指向 argv 与环境变量数组 //以下为调用函数 __libc_start_main 压入参数 pushl %esp //压入栈底地址,即栈的最高地址 pushl %edx //压入函数指针,该函数完成与动态加载有关的收尾工作 pushl $__libc_csu_fini //压入函数指针,该函数完成 main 结束后的收尾工作 pushl $__libc_csu_init //压入函数指针,该函数完成 main 调用前的初始化工作 pushl %ecs //压入argv 与环境变量数组 pushl %esi //压入argc pushl main // 压入 main 函数的指针 call __libc_start_main //调用另一个初始化函数,参数为上述压栈数据,从右至左压栈 hlt // 避免调用 __libc_start_main 函数中没有成功调用 exit ,hlt 将强制终止程序
2)_start 函数调用另一个函数 __libc_start_main,完成对运行环境的初始化,且传入该函数的参数为七个参数,上面代码中压入栈的七个数据从上到下对应调用函数中从右至左的参数。__lib_start_main函数的代码与解释如下:
int __libc_start_main( int(*main)(int, char**, char**), //第一个参数,main 函数的指针 int argc, char * __unbounded * __unbounded ubp_av, // 第三个参数,包含了 argv 与环境变量的数组 _typeof(main) init, //第四个参数,初始函数指针 void(*fini)(void), //第五个参数,结束函数指针 void(*rtld_fini)(void), //第六个参数,处理动态链接的函数 void * __unbounded stack_end //第七个参数,栈底地址 ) { char** ubp_ev = &ubp_av[argc + 1]; //使 ubp_ev 执行 argv __environ = ubp_env; // 使 __environ 执行环境变量 __libc_stack_end = stack_end; //存储栈底地址 //...省略许多步骤 __cxa_atexit(rtld_fini, NULL, NULL); //注册在 main 结束后的函数调用 //... _cxa_atexit(fini, NULL, NULL); //... result = main(argc, argv, __environ); //调用 main 函数 exit(result); //执行结束函数 }
函数在执行完 main 函数后,将调用 exit 退出进程,而 exit 中,将执行注册的收尾函数,对于非正常结束的进程,也会调用 exit,因此确保注册的收尾函数无论是在正常结束函数非正常结束时均会被调用。
* exit 调用所有注册的收尾函数后,将调用 _exit() 函数,该函数将直接结束,且该函数最后也有一个 "hlt" ,其功能与 _start 中的一样,预防程序调用 exit 系统调用失败时,无法结束进程。
相关文章推荐
- Java IO7:管道流、对象流
- [BZOJ1562][NOI2009] 变换序列
- 无头单链表删除随机节点
- Android adb命令的使用方法
- kafka.common.ConsumerRebalanceFailedException :log-push-record-consumer-group_mobile-pushremind02.lf
- 对关系数据库标准语言SQL的简单认识
- Linux less 命令 【转载】
- opencv3计算轮廓的长度-arcLength函数
- Android实现图片滚动控件,含页签功能
- Tricks of Android's GUI
- 01.ZooKeeper安装和介绍
- Android_05_多线程断点续传下载
- 斤斤计较的人永远不会获得幸福
- 使用cookie绕过验证码进行模拟登录
- opencv3计算轮廓的面积-contourArea函数
- 熟悉ALM环境,建立域,项目,用户名等; 练习创建发布树。
- QT Win7开发环境安装配置程
- 【C】贪心算法
- Linux下的socket编程实践(七) I/O多路复用技术之select模型
- LA4998 Simple Encryption