C程序的内存布局

C程序的内存布局

一个C程序是由下面这些组成的:

  • 文本段,被CPU执行的机器指令。通常文本段是共享的,所以经常执行的程序只要复制就可以,如:文本编辑器、C编译器、shell等等。通常文本段是只读的,为了防止程序意外修改指令。
  • 初始数据段或数据段,包含在程序中初始化的变量。例如,C声明:
    int  maxcount = 99;
    初始化常量99做为变量maxcount的值,存储在初始数据段。
  • 非初始数据段或BSS段,BBS——Block Started by Symbol。在这个段中存储的数据在程序执行前被内核初始化成算数0或null指针,C声明:
    long sum[1000];
    这将使变量存储在BBS。
  • 堆,动态内存分配通常在这里。历史上,堆被分配在未初始化数据和栈之间。
  • 栈,存储自动变量,每次程序启动的信息被保存在这里。每次程序调用,程序的返回地址或某些调用者的环境信息,例如,一些机器的寄存器被存储在栈。最新调用程序的自动变量或临时变量会分配到栈的上面。程序递归使用的就是栈,每次递归程序调用它自己,就会使用一个新的栈框架,所以递归程序中的一组新变量不会影响另一组同样的变量。

这几个段的典型顺序是这样的:

(低地址)文本段、初始化数据段、BBS、堆、栈、命令行参数和环境变量(高地址)

文本段和初始化数据段是被exec从程序中读取。非初始化数据段(BBS)被exec初始化成0。

Intel x86处理器上安装的LINUX,它的文本段开始位置在0x08048000,栈底开始在0xC0000000下面。

堆、栈共用一段空间,通常这段空间很大。堆、栈在这段空间的两端向中间增长。

未初始化数据段并不保存在磁盘的程序文件中,这是因为在程序运行之前内核会把它设置成0。只有文本段和初始化数据段做为程序的一部分存储在程序文件中。

size命令报告了程序的文本、数据、和BBS段大小。如:

    $ size /usr/bin/cc /bin/sh
       text     data   bss     dec     hex   filename
      79606     1536   916   82058   1408a   /usr/bin/cc
     619234    21120 18260  658614   a0cb6   /bin/sh

第4、5列以十进制和十六进制形式显示了前三列的总和。

发表评论