C中的局部和静态变量(续)

时间:2012-11-27 11:14:29

标签: c gcc assembly static

last question的基础上构建我试图弄清楚.local.comm指令的确切运作方式,特别是它们如何影响C中的关联和持续时间。

所以我进行了以下实验:

static int value;

生成以下汇编代码(使用gcc):

.local  value
.comm   value,4,4

初始化为零时,会产生相同的汇编代码(使用gcc):

.local  value
.comm   value,4,4

这听起来合乎逻辑,因为在这两种情况下我都希望变量存储在bss段中。此外,在使用ld --verbose进行调查后,看起来所有.comm变量确实都放在了bss段中:

  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   // ...
  }

当我将变量初始化为非零值时,编译器会按照我的预期在数据段中定义变量,但会产生以下输出:

        .data
        .align 4
        .type   value, @object
        .size   value, 4
value:
        .long   1

除了不同的段(分别为bss和数据),感谢您之前我现在理解的帮助,我的变量在第一个示例中被定义为.local.comm,但在第二个示例中没有被定义为{{1}}。任何人都可以解释每个案例产生的两个产出之间的区别吗?

2 个答案:

答案 0 :(得分:2)

.local指令将符号标记为本地非外部可见符号,如果它尚不存在则创建它。 0初始化的局部符号是必要的,因为.comm声明但不定义符号。对于1初始化变体,符号本身(value:)声明符号。

使用.local.comm基本上是一种黑客攻击(或者至少是一种速记);另一种方法是将符号明确地放入.bss

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

答案 1 :(得分:1)

由于安全原因,Linux内核在分配后将进程的虚拟内存归零。因此,编译器已经知道内存将用零填充并进行优化:如果某个变量初始化为0,则无需在可执行文件中保留空间(.data部分实际占用一些空间在ELF可执行文件中,.bss部分仅存储其长度,假设其初始内容为零。