bss 和数据段中的整型变量大小

Jai*_*ach 4 c linux operating-system memory-management

我正在使用一个测试程序来理解内核版本为 2.6.32-279.el6.x86_64 的 linux 6.3 上的 C 内存模型。

首先我编译了下面的代码,

#include <stdio.h>
int main(void)
{
    static int i = 100; /* Initialized static variable stored in DS*/
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在运行 size 命令时,我得到了以下结果,

[root@rachitjain jan14]# size a.out
   text    data     bss     dec     hex filename
   1040     488      16    1544     608 a.out
Run Code Online (Sandbox Code Playgroud)

然后,在删除静态变量“i”的初始化后,我的代码变为,

include <stdio.h>
int main(void)
{
    static int i ;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面编译后的运行大小,

[root@rachitjain jan14]# size a.out
   text    data     bss     dec     hex filename
   1040     484      24    1548     60c a.out
Run Code Online (Sandbox Code Playgroud)

bss 部分增加了 8 个字节,但 data 部分仅减少了 4 个字节。为什么移动到 bss 段时大小会加倍为整数?

我也测试了这个角色和浮动,观察到相同的行为。

小智 5

看,答案是.bss部分有在64位上对齐的要求,而.data没有这个要求。

你怎么能看到这个?当您构建程序时,ld 使用默认链接描述文件来构建您的程序。添加-Wl,-verbose就可以看到:

g++ main.cpp -Wl,-verbose
Run Code Online (Sandbox Code Playgroud)

当您构建 64 位应用程序时,这是 .bss 部分的默认对齐方式:

  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 64 / 8 : 1);
  }
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,ALIGN(. != 0 ? 64 / 8 : 1);告诉你对齐到 8 个字节

当您构建 32 位应用程序 (g++ -m32 main.cpp -Wl,-verbose) 时,这是 .bss 部分的默认对齐方式:

  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 32 / 8 : 1);
  }
Run Code Online (Sandbox Code Playgroud)

您的 .data 部分显然在默认链接器脚本中没有任何 ALIGN 命令:

  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
Run Code Online (Sandbox Code Playgroud)

有用的链接: