快速业务通道

linux:入口函数和程序初始化

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-05-01

如果把一个程序比作一个世界,那么程序的启动无疑就是“创世”.在本章里,我们将从程序的创世开始,接触到在程序背后另一类默默服务的团体.它们能够程序正常地启动,能够各种我们熟悉的函数发挥作用,它们就是应用程序的运行库.

  11.1 入口函数和程序初始化

  11.1.1 程序从main开始吗

  正如基督徒认为世界的诞生起于7天创世一样,任何一个合格的C/C 程序员都应该知道一个事实:程序从main函数开始.但是事情的真相真是如此吗?如果你善于观察,就会发现当程序执行到main函数的第一行时,很多事情都已经完成了:

 

  从代码中我们可以看到,在程序刚刚执行到main的时候,全局变量的初始化过程已经结束了(a的值已经确定),main函数的两个参数(argc和argv)也被正确传了进来.此外,在你不知道的时候,堆和栈的初始化悄悄地完成了,一些系统I/O也被初始化了,因此可以放心地使用printf和malloc.

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

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

  void foo(void)

  {

  printf("bye!n");

  }

  int main()

  {

  atexit(&foo);

  printf("endof mainn");

  }

  用atexit函数注册的函数的调用时机是在main结束之后,因此这段代码的输出是:

  endof main

  bye!

  所有这些事实都在为“main创论”提供不利的证据:操作系统装载程序之后,运行的代码并不是main的第一行,而是某些别的代码,这些代码负责准备好main函数执行所需要的环境,并且负责调用main函数,这时候你才可以在main函数里放心大胆地写各种代码:申请内存、使用系统调用、触发异常、访问I/O.在main返回之后,它会记录main函数的返回值,调用atexit注册的函数,然后结束进程.


运行这些代码的函数称为入口函数或入口点(Entry Point),视平台的不同而有不同的名字.程序的入口点实际上是一个程序的初始化和结束部分,它往往是运行库的一部分.一个典型的程序运行步骤大致如下:

  l 操作系统在创建进程后,把控制权交到了程序的入口,这个入口往往是运行库中的某个入口函数.

  l 入口函数对运行库和程序运行环境进行初始化,包括堆、I/O、线程、全局变量构造,等等.

  l 入口函数在完成初始化之后,调用main函数,正式开始执行程序主体部分.

  l main函数执行完毕以后,返回到入口函数,入口函数进行清理工作,包括全局变量析构、堆销毁、关闭I/O等,然后进行系统调用结束进程.

  11.1.2 入口函数如何实现

  大部分程序员在平时都接触不到入口函数,为了对入口函数进行详细的了解,本节我们将深入剖析glibc和MSVC的入口函数实现.

  GLIBC入口函数

  glibc的启动过程在不同的情况下差别很大,比如静态的glibc和动态的glibc的差别,glibc用于可执行文件和用于共享库的差别,这样的差别可以组合出4种情况,这里只选取最简单的静态glibc用于可执行文件的时候作为例子,其他情况诸如共享库的全局对象构造和析构跟例子中稍有出入,我们在本书中不一一详述了,有兴趣的读者可以根据这里的介绍自己阅读glibc和gcc的源代码,相信能起到举一反三的效果.下面所有关于Glibc和MSVC CRT的相关代码分析在不额外说明的情况下,都默认为静态/可执行文件链接的情况.

  读者可以免费下载到Linux下glibc的源代码,在其中的子目录libc/csu里,有关于程序启动的代码.glibc的程序入口为_start(这个入口是由ld链接器默认的链接脚本所指定的,我们也可以通过相关参数设定自己的入口)._start由汇编实现,并且和平台相关,下面可以单独看i386的_start实现:


这里省略了一些不重要的代码,可以看到_start函数最终调用了名为__lib_start_main的函数.加粗部分的代码是对该函数的完整调用过程,其中开始的7个压栈指令用于给函数传递参数.在最开始的地方还有3条指令,它们的作用分别为:

  l xor

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号