2010-11-05 35 views
1
  1. static int i = 0; 哪里将我分配的变量?它是在BSS还是初始化数据段?
  2. 存储类'extern'和'register'的变量存储在哪里?

我可以请提供代码段,以交叉检查上述C程序存储器映射

+2

有趣的事情:downvotes +的最爱。我想这意味着“我知道答案,但我不喜欢你问你的问题的方式”:) – 2010-11-05 15:22:09

+3

@Armen Tsirunyan - Nah,只有更多的人有相同的功课。 – Ishtar 2010-11-05 15:36:37

+2

术语BSS和初始化的数据段在C中没有意义。语言标准完全取决于实现来决定将不同存储类别的变量放在哪里。 – JeremyP 2010-11-05 16:14:32

回答

3

不知道你正在处理的具体实现是不可能的。在某些情况下,由于您提供了初始化程序,因此static int i=0;将存储在已初始化的数据段中。在其他情况下,无论如何BSS都将被初始化,所以链接器无论如何都会把它放在那里。如果您指定了不同的值(例如,static int i=12345;),那么您可以更好地确保将其置于初始化的数据段中。

extern并不真正确定链接器将放置变量的位置。如上所述:如果链接器知道(或安排)BSS是零初始化的,那么在BSS中可能没有指定初始化器的外存。如果BSS不是零初始化的,它通常必须位于初始化的数据段中。

register基本上相当于auto - 它们都在运行时分配,通常在寄存器或堆栈中。

就验证它而言,这更加依赖于个体实现。您通常会通过查看链接器映射文件之类的东西来查找;如果你想自己弄清楚,它很可能会涉及到所使用的符号格式,或者为系统开发可执行格式的内部结构。

1

如前所述,这取决于。

在我的情况(GCC & Linux的),我决定去看看:

int main (int argc, char **argv) 
{ 
    static int initialized_static_var = 0; 
    static int uninit_static_var; 
    register int reg_var; 
    extern int extern_var; 

    return 0; 
} 

然后objdump的-x上的可执行文件(编辑为简洁起见):

0804a018 l  O .bss 00000004    uninit_static_var.1704 
0804a01c l  O .bss 00000004    initialized_static_var.1703 

无论是寄存器变量和未使用的extern都出现在符号表中,如果您仔细考虑,这是有意义的。