C 为什么int类型在BSS部分占用8字节,而在数据部分占用4字节

C 为什么int类型在BSS部分占用8字节,而在数据部分占用4字节,c,linux,gcc,C,Linux,Gcc,我试图学习C程序可执行文件的结构。我的环境是GCC和64位Intel处理器 考虑以下C代码a.cc #include <cstdlib> #include <cstdio> int x; int main(){ printf("%d\n", sizeof(x)); return 10; } 在我添加了另一个初始化的全局变量y之后 int y=10; 显示大小a(其中a是a.cc中可执行文件的名称) 我们知道,BSS部分存储未初始化全局变量的大小,DATA

我试图学习C程序可执行文件的结构。我的环境是GCC和64位Intel处理器

考虑以下C代码
a.cc

#include <cstdlib>
#include <cstdio>

int x;

int main(){
  printf("%d\n", sizeof(x));
  return 10;
}
在我添加了另一个初始化的全局变量y之后

int y=10; 
显示
大小a
(其中
a
是a.cc中可执行文件的名称)

我们知道,
BSS
部分存储未初始化全局变量的大小,
DATA
存储初始化的全局变量

  • 为什么
    int
    在BSS中占用8个字节?我的代码中的
    sizeof(x)
    表明
    int
    实际上占用了4个字节。
  • 由于
    int
    应该需要4个字节,因此
    int y=10
    向数据添加了4个字节,这是有意义的。但是,为什么它会向BSS添加4个字节?
  • 删除两行
    #include…
    后,两个
    size
    命令之间的差异保持不变

    更新: 我认为我对BSS的理解是错误的。它可能不会存储未初始化的全局变量。正如维基百科所说,“BSS在运行时需要的大小记录在对象文件中,但BSS(与数据段不同)不会占用对象文件中的任何实际空间。”例如,即使是一行C代码
    int main(){}
    也有
    BSS 8


    BSS的8或16是否来自
    对齐

    不是,它占用4个字节,无论它位于哪个段中。您可以使用
    nm
    工具(来自GNU binutils包)和
    -S
    参数来获取对象文件中所有符号的名称和大小。无论出于何种原因,您可能会看到编译器的次要影响,包括或不包括某些其他符号

    例如:

    $ cat a1.c
    int x;
    $ cat a2.c
    int x = 1;
    $ gcc -c a1.c a2.c
    $ nm -S a1.o a2.o
    
    a1.o:
    0000000000000004 0000000000000004 C x
    
    a2.o:
    0000000000000000 0000000000000004 D x
    

    一个对象文件在未初始化数据段(
    C
    )中有一个名为
    x
    的4字节对象,而另一个对象文件在初始化数据段(
    D
    )中有一个名为
    x
    的4字节对象。

    您看过汇编代码了吗?它可以在bss中声明并使用later@JoachimPileborg我在维基百科上看到了这一点,这让我对BSS部分感到困惑。谢谢。当没有全局变量时,<代码> BSS 是0?你是在谈论C还是C++?您遍及C,但您的示例程序是C++。如果删除变量
    x
    ,您得到的BSS大小是多少?此代码不是有效的C,并且
    size-o
    可能无法打印8,因为
    -o
    表示“八进制”。投票以不可复制的方式关闭。+1运行库中链接的启动代码很可能会占用
    size
    显示的额外空间(如果我不得不猜测的话(总是危险的),我会说它是类似于
    errno
    或其他一些商品的东西;例如,mach-o图像包括dynalib loader的存根活页夹)。谢谢。我想更多地了解可执行文件的结构。例如,BSS到底是做什么的?@penzhang:BSS段通常是一个有地址和大小的段(因此可以映射到内存),但不包含实际的初始化数据(因此没有存储到文件中的内容)。加载后,可作为可读写存储器使用;就像普通数据一样。@Jongware谢谢。因此,虽然数据和文本将被复制到内存中,但BSS不会?BSS是否可以作为一个通知给操作系统,让linux知道在加载程序时如何分配程序所需的内存(除了文本和数据)?@penzhang:听起来不错。找到平台可执行文件格式的良好描述,并找到一个工具(或编写工具!)来转储原始数据。您将看到没有与BSS段关联的文件数据。
     text      data     bss     dec     hex filename
     1134       556      12    1702     6a6 a
    
    $ cat a1.c
    int x;
    $ cat a2.c
    int x = 1;
    $ gcc -c a1.c a2.c
    $ nm -S a1.o a2.o
    
    a1.o:
    0000000000000004 0000000000000004 C x
    
    a2.o:
    0000000000000000 0000000000000004 D x