最近,我了解到.bss
段存储了未初始化的数据。但是,当我尝试如下的小程序并在终端中使用size(1)
命令时,即使添加了一些全局变量,.bss段也没有改变。我误解了什么吗?
jameschu@aspire-e5-573g:~$ cat test.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
jameschu@aspire-e5-573g:~$ gcc -c test.c
jameschu@aspire-e5-573g:~$ size test.o
text data bss dec hex filename
89 0 0 89 59 test.o
jameschu@aspire-e5-573g:~$ cat test.c
#include <stdio.h>
int a1;
int a2;
int a3;
int main(void)
{
printf("hello world\n");
return 0;
}
jameschu@aspire-e5-573g:~$ gcc -c test.c
jameschu@aspire-e5-573g:~$ size test.o
text data bss dec hex filename
89 0 0 89 59 test.o
答案 0 :(得分:3)
这是因为全局变量的工作方式。
正在解决的问题是,可以在几个.c
文件中声明一个全局变量而不初始化,并且不会出现重复的符号错误。也就是说,每个全局未初始化的声明都像 weak 声明一样工作,如果没有其他声明包含初始化,则可以将其视为external
。
编译器如何实现?易:
bss
段中添加该变量,而是将其添加到COMMON
段。COMMON
变量,并丢弃已在其他部分中的任何人。其余的将移至可执行文件的bss
。这就是为什么你在目标文件的bss
中看不到你的变量,但你在可执行文件中看到了。
您可以使用size
的更现代的替代方法检查对象部分的内容,例如objdump -x
。并注意变量如何放在*COM*
。
值得注意的是,如果将全局变量声明为static
,则表示该变量属于该编译单元,因此未使用COMMON
并获得您期望的行为:
int a;
int b;
static int c;
$ size test.o
text data bss dec hex filename
91 0 4 95 5f test.o
初始化为0
会得到类似的结果。
int a;
int b;
int c = 0;
$ size test.o
text data bss dec hex filename
91 0 4 95 5f test.o
但是,初始化为0
以外的任何内容都会将该变量移至data
:
int a;
int b = 1;
int c = 0;
$ size test.o
text data bss dec hex filename
91 4 4 99 5f test.o