1. 存储空间布局
static int g_init = 1; // data 段
static int g_uninit; // bss 段
int main() {
static int s_init = 1; // data 段
static init s_uninit; // bss 段
return 0;
}
历史沿袭至今,C 程序一直由下列几部分组成:
正文段(text)
这是由 CPU 执行的机器指令部分。通常,正文段是可以共享的(只读),所以,即使是频繁执行的程序(如文本编辑器,C 编译器和 Shell 等)在存储器中也只有一个副本。
初始化数据段(data)
包含了程序中需明确地赋初值的变量。例如,C 程序中任何函数之外(全局函数)的声明:
int maxcount = 99;
包含了经过初始化的全局变量和静态变量,以及他们的值。
未初始化数据段(bss)
内核将此段中的数据初始化为 0 或空指针。
包括,包含未经初始化的全局变量和静态变量。
栈(stack)
堆(heap)
通常在堆中进行动态存储分配。堆位于未初始化数据段和栈之间。
对于 32 位 Intel X86 处理器上的 Linux,正文段从 0x08048000 单元开始,栈底则在 0xC000000 之下开始(在这种特定结构下,栈从高地址向低地址方向增长)。堆顶和栈顶之间未用的虚地址空间很大。
未初始化数据段的内容并不存放在磁盘程序文件中,原因在于,内核在程序开始运行前将它们都设置为 0. 需要存放在磁盘程序文件中的只有正文段和初始化数据段。
2. 用 size 命令分析 linux 程序内核段的分布
size 命令的输出不包括 stack(栈) 和 heap(堆) 的部分。只包括文本段(text), 数据段(data),未初始化数据段(bss)三部分。
$ size /usr/bin/cc /bin/sh
text data bss dec hex filename
900967 8032 9696 918695 e04a7 /usr/bin/cc
143301 4792 11312 159405 26ead /bin/sh