本部分内容详见《C专家编程》P119
查看可执行文件中的段
1.编译“hello world”程序,在可执行文件中执行ls -l,得到文件的总体大小。运行size得到文件里各个段的大小。
2.增加一个全局的int[1000]数组声明,重新进行编译,再用上面的命令得到总体及各个段的大小,注意前后的区别。
3.现在,在数组的声明中增加初始值(记住,C语言并不强迫对数组进行初始化时为每个元素提供初始值)。这将使数组从BSS段转换到数据段。重复上面的测量,注意各个段前后大小的区别。
4.现在,在函数内声明一个巨大的数组。然后再声明一个巨大的局部数组,但这次加上初始值。重复上面的测量。定义于函数内部的局部数组存储在可执行文件中吗?有没有初始化有什么不同吗?
5.如果在调试状态下编译,文件和段的大小有没有变化?是为了最大程度的优化吗?
分析上面“编程挑战”的结果,使自己确信:
- 数据段保存在目标文件中。
- BSS段不保存在目标文件中(除了记录BSS段在运行时所需要的大小)。
- 文本段是最容易受优化措施影响的段。
- a.out文件的大小受调试状态下编译的影响,但段不受影响。
helloworld.c的文件最终如下:
#include <stdio.h>
int global_array[1000] = {100, 101, 102};
void SayGoodBye(void);
int main(void)
{
printf("hello Linux world");
int main_array[1000] = {10, 20, 30, 40};
SayGoodBye();
return 0;
}
void SayGoodBye(void)
{
int goodbye_array[1000] = {1024, 2048, 4096};
printf("good bye user!");
}
以下命令按照文中步骤依次修改上文代码(过程不赘述),运行size后的数据如下所示:
[volnet@GoCool c]$ echo "size helloworld1"; size helloworld1; echo "size helloworld2"; size helloworld2; echo "size helloworld3"; size helloworld3; echo "size helloworld4"; size helloworld4;
size helloworld1
text data bss dec hex filename
1015 252 8 1275 4fb helloworld1
size helloworld2
text data bss dec hex filename
1015 252 4032 5299 14b3 helloworld2
size helloworld3
text data bss dec hex filename
1015 4280 8 5303 14b7 helloworld3
size helloworld4
text data bss dec hex filename
1270 4280 8 5558 15b6 helloworld4
注:
BSS的全称是:Block Started by Symbol(由符号开始的块),它是旧式IBM704汇编程序的一个伪指令,UNIX借用了这个名字,至今依然沿用。