对于目标文件而言,“段”是二进制文件中简单的区域,里面保存了和某种特定类型(如符号表条目)相关的所有信息。section 是 ELF 文件中的最小组织单位。一个段一般包含几个section。
不要把UNIX中段的概念跟Intel X86架构中段的概念混淆。
在UNIX中,段表示一个二进制文件相关的内容块。
在Intel x86的内存模型中,段表示一种设计的结果。在这种设计中(基于兼容性原因),地址空间并非一个整体,而是分成一些64K大小的区域,称之为段。
当在一个可执行文件中运行 size 命令时,它会告诉你这个文件中的三个段(文本段,数据段和bss段)的大小:
% size a.out
text data bss dec hex filename
1548 4236 4 1133 46d a.out
nm和dump命令可以检查可执行文件的内容!
BSS段只保存没有值得变量。(BSS:Block Started by Symbol 由符号开始的块)
举例:
$ cat helloworld.c
#include <stdio.h>
int main(void)
{
printf("hello world!/n");
return 0;
}
$ ls -l a.out
4692
$ ls -l helloworld.c
77
$ size a.out
text data bss dec hex filename
843 260 4 1107 453 a.out
增加一个全局的int array[1000]; 数组声明。重新编译得:
$ ls -l a.out
4714
$ size a.out
text data bss dec hex filename
843 260 4032 5135 140f a.out
对数组进行初始化: int array[1000] = {0, 10, 20, 0};
得:
$ ls -l a.out
8734
$ size a.out
text data bss dec hex filename
843 4280 4 5127 1407 a.out
分析上面的“编程结果”,使自己确信:
(1)数据段保存在目标文件中;
(2)SS段不保存在目标文件中(除了记录BSS段在运行时所需要的大小)。
(3)文本段是最容易受优化措施影响的段。
(4) a.out 文件的大小受调试状态下编译的影响,但段不受影响。