6

我从size命令中得到了意外的输出。

Afaik 初始化了存储在段中的全局和静态变量data,未初始化并初始化为存储在bss段中的 0 个全局/静态变量。

printf("%d",sizeof(int));给出int大小 4。但是,bssdata并没有相应地增加到 4。

#include <stdio.h>
int main()
{
    return 0;
}

C:\Program Files (x86)\Dev-Cpp\MinGW64\bin>size memory-layout.exe
   text    data     bss     dec     hex filename
  10044    2292    2512   14848    3a00 memory-layout.exe

#include <stdio.h>
int g; //uninitialised global variable so, stored in bss segment
int main()
{
    return 0;
}

C:\Program Files (x86)\Dev-Cpp\MinGW64\bin>size memory-layout.exe
   text    data     bss     dec     hex filename
  10044    2292    2528   14864    3a10 memory-layout.exe

为什么bss增加了 16 (2528 - 2512) 而不是 4?(在上面的代码中)

#include <stdio.h>
int g=0; //initialised to 0 so, stored in bss segment
int main()
{
    return 0;
}

C:\Program Files (x86)\Dev-Cpp\MinGW64\bin>size memory-layout.exe
   text    data     bss     dec     hex filename
  10044    2292    2512   14848    3a00 memory-layout.exe

尽管使用了全局变量,但没有增量bss。为什么?

 #include <stdio.h>
int main()
{   static int g; //should be on bss segment
    return 0;
}

C:\Program Files (x86)\Dev-Cpp\MinGW64\bin>size memory-layout.ex
   text    data     bss     dec     hex filename
  10044    2292    2512   14848    3a00 memory-layout.exe

bss尽管使用了静态变量,但段中没有增量,为什么?

我还有一个问题,dec这里代表什么?

4

3 回答 3

2

首先要考虑的是内存对齐。可以填充变量和部分以使它们位于地址边界上。在第二个示例中,您看到比第一个增加了 16,这表明填充 16 字节边界(2512 / 16 = 157、2528 / 16 = 158)。这完全取决于实现。

就 C 而言,第二个示例与第三个示例不同,因为编译器无法知道int g是定义还是仅是另一个文件中定义的整数的声明(可以是任何值)。它为链接器留下了一个参考来处理,这可能会导致填充的差异。

在第三个示例中,g显式定义并设置为 0,因此编译器知道将其放入 BSS 部分。

可以使用我系统中生成的程序集来证明这一点:

with int g(在这种情况下没有定义 BSS 部分)

.comm   g,4,4

这是链接器处理符号的指令,因为编译器无法完全确定如何处理它。

int g = 0

    .bss
    .align 4
    .type   g, @object
    .size   g, 4
g:
    .zero   4

在这里,编译器确切地知道要做什么,因此为符号定义了一个 BSS 部分。

就我而言,链接器以相同的方式解决这些问题。两者都放置在相同地址的 BSS 部分中,因此 BSS 大小没有差异。您可以使用类似的实用程序检查布局nm

nm -n file2 file3 | grep g$

000000000060103c B g
000000000060103c B g

即在这个系统g上是在同一个地址。或者,使用调试器:

(gdb) info symbol 0x60103c
g in section .bss of /tmp/file2

另请注意,在最后一个示例中,可以优化变量,因为它具有内部链接。

至于dec,它只是十进制部分的总和。

于 2015-03-30T22:09:59.380 回答
1

这是来自 linux 上的 gcc:

No Variable
   text    data     bss     dec     hex filename
    915     248       8    1171     493 none.out
Uninitialized Global
   text    data     bss     dec     hex filename
    915     248      12    1175     497 u_g.out
Initialized Global to 123
   text    data     bss     dec     hex filename
    915     252       8    1175     497 i_g.out
Initialized Local to 124
   text    data     bss     dec     hex filename
    915     252       8    1175     497 i_l.out
Initialized Global to 0
   text    data     bss     dec     hex filename
    915     248      12    1175     497 i_g_0.out
Initialized Local to 0
   text    data     bss     dec     hex filename
    915     248      12    1175     497 i_l_0.out

这是来自 Windows 上的 mingw64:

No Variable
   text    data     bss     dec     hex filename
   3173    1976     448    5597    15dd none.out
Uninitialized Global
   text    data     bss     dec     hex filename
   3173    1976     464    5613    15ed u_g.out
Initialized Global to 123
   text    data     bss     dec     hex filename
   3173    1976     448    5597    15dd i_g.out
Initialized Local to 124
   text    data     bss     dec     hex filename
   3173    1976     448    5597    15dd i_l.out
Initialized Global to 0
   text    data     bss     dec     hex filename
   3173    1976     480    5629    15fd i_g_0.out
Initialized Local to 0
   text    data     bss     dec     hex filename
   3173    1976     480    5629    15fd i_l_0.out

因此,尽管我对这个问题没有最终答案(不适合发表评论),但结果让我怀疑 Windows 和/或 MinGW 的可执行文件格式(即不是 gcc)。

于 2015-04-03T12:50:33.633 回答
0

BSS 仅包含未显式初始化的静态和全局值。即使您将其显式初始化为与未显式初始化时将被初始化的值相同的值,显式初始化的事实意味着它不属于 bss。

于 2015-04-05T07:26:37.060 回答