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列以十进制和十六进制形式显示了前三列的总和。