最近,我了解到.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
Run Code Online (Sandbox Code Playgroud)
这是因为全局变量的工作方式。
正在解决的问题是,可以在多个文件中声明全局变量而不对其进行初始化.c,并且不会出现重复符号错误。也就是说,每个全局未初始化声明的工作方式都类似于弱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
Run Code Online (Sandbox Code Playgroud)
初始化为0会得到类似的结果。
int a;
int b;
int c = 0;
$ size test.o
text data bss dec hex filename
91 0 4 95 5f test.o
Run Code Online (Sandbox Code Playgroud)
但是,初始化为除此以外的任何值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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
426 次 |
| 最近记录: |