简体   繁体   English

为什么我不在BSS中获得静态变量?

[英]Why don't I get static variables in the BSS?

To the best of my understanding, static variables that are not explicitely initialized (and, with GCC, even those that are explicitely initialized to zero if -fzero-initialized-in-bss is set, which is the case by default) are usually stored in the BSS segment. 据我所知,未明确初始化的静态变量(并且,对于GCC,甚至那些-fzero-initialized-in-bss设置了-fzero-initialized-in-bss明确初始化为零的那些,通常是默认情况下)在BSS部分。 Yet, it seems that when I try to inspect that behaviour, those variables are stored in the general data section (with initialized globals). 然而,当我尝试检查该行为时,这些变量似乎存储在通用数据部分中(使用初始化的全局变量)。 If I compile (with -O0 for good measure) and run: 如果我编译(使用-O0进行测量)并运行:

#include <stdio.h>
#include <stdlib.h>

extern char etext, edata, end;

int i = 42;

int main(int argc, char* argv[])
{
        static int j;
        printf ("end of program (etext) = %10p\n",&etext);
        printf ("end of initialized data (edata) = %10p\n",&end);
        printf ("end of uninitialized data (end) = %10p\n",&end);
        printf ("=====\n");
        printf ("Value of i (initialized global) : %d\n",i);
        printf ("Address of i : %10p\n",&i);
        printf ("Value of j (static with no explicit initialization) : %d\n",j);
        printf ("Address of i : %10p\n",&j);
        return 0;
}

I get the output: 我得到输出:

end of program (etext) =   0x40067d
end of initialized data (edata) =   0x600af0
end of uninitialized data (end) =   0x600af0
=====
Value of i (initialized global) : 42
Address of i :   0x600ae0
Value of j (static with no explicit initialization) : 0
Address of i :   0x600ae8

So i and j are stored at contiguous memory address, between &etext and &edata , which is the regular data section. 所以ij存储在连续的内存地址, &etext&edata ,这是常规数据部分。 Furthermore, it seems that &edata == &end which, if I understand correctly, would mean that the BSS is empty. 此外,似乎&edata == &end ,如果我理解正确,那将意味着BSS是空的。

Now I realize that where the compiler puts which variable is an implementation choice and the results it produces is correct. 现在我意识到编译器放置哪个变量是一个实现选择,它产生的结果是正确的。 But I am just wondering why I get that behaviour, and if there is a way to tell gcc to explicitely put such variables in the BSS (I didn't see any obvious solution in the manual). 但我只是想知道为什么我会得到这种行为,如果有办法告诉gcc明确地将这些变量放在BSS中(我在手册中没有看到任何明显的解决方案)。

You have an error in your code. 您的代码中有错误。 You print the address of end for both edata and end, so of course you assume edata == end, which they are not. 你打印edata和end的end的地址,所以当然你假设edata == end,它们不是。

When I fixed your code and run it I get: 当我修复你的代码并运行它时,我得到:

end of program (etext) = 0x8048578 程序结束(etext)= 0x8048578
end of initialized data (edata) = 0x804988c 初始化数据的结尾(edata)= 0x804988c
end of uninitialized data (end) = 0x8049894 未初始化数据的结束(结束)= 0x8049894

Value of i (initialized global) : 42 i的值(初始化全局):42
Address of i : 0x8049888 i的地址:0x8049888
Value of j (static with no explicit initialization) : 0 j的值(没有显式初始化的静态):0
Address of j : 0x8049890 地址j:0x8049890

So clearly j is in the area between edata and end and not in the same place as i . 所以很明显j是edata和end之间的区域,而不是和i在同一个地方。

(gcc 5.2.1 20150911 (Debian 5.2.1-17), 32bit) (gcc 5.2.1 20150911(Debian 5.2.1-17),32bit)

The BSS in the executable image is just a number that says how many bytes to reserve upon load for the uninitialized variables. 可执行映像中的BSS只是一个数字,表示在未初始化的变量加载时要保留多少字节。 In this way the image doesn't get unwieldly large for many of these uninitialized variables. 通过这种方式,对于许多未初始化的变量,图像不会变得非常大。 When the number is very small, such as in your example, there is hardly any saving and only overhead and the compiler may have decided to place them all in the DATA segment. 当数字非常小时,例如在您的示例中,几乎没有任何保存和开销,编译器可能已决定将它们全部放在DATA段中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM