gpt4 book ai didi

c - 为什么添加变量后.bss段没有增加?

转载 作者:IT王子 更新时间:2023-10-29 01:25:32 32 4
gpt4 key购买 nike

最近了解到.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

最佳答案

这是因为全局变量的工作方式。

正在解决的问题是可以在多个 .c 文件中声明一个全局变量,无需初始化,并且不会出现重复符号错误.也就是说,每个全局未初始化的声明都像一个声明,如果没有其他声明包含初始化,则可以将其视为外部

编译器是如何实现的?简单:

  • 编译时,不是将该变量添加到 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

关于c - 为什么添加变量后.bss段没有增加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47727604/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com