variables的值存储在C中

在以下代码段中:

int func() { int a=7; return a; } 

代码段中值7存储在可执行文件中吗? 或者它是在数据段还是在代码段? 答案取决于操作系统还是编译器?

Solutions Collecting From Web of "variables的值存储在C中"

每个可执行格式都有一些部分。 其中之一是text ,包含汇编 – 二进制代码。 其中之一就是在malloc -ed数据被找到的heap ,并且在stack上存储局部变量。 还有其他几个,但现在并不重要。 以上三点到处都是。

现在,您的a等本地数据驻留在堆栈上。 在可执行文件中,该值存储在text部分中。

我已经添加了一个main代码(返回0),用-g编译然后做了objdump -CDgS a.out然后搜索0x424242 (我用一个随机出现在代码中的值较小的值替换了7 )。

 00000000004004ec <func>: int func() { 4004ec: 55 push %rbp 4004ed: 48 89 e5 mov %rsp,%rbp int a=0x42424242; 4004f0: c7 45 fc 42 42 42 42 movl $0x42424242,-0x4(%rbp) return a; 4004f7: 8b 45 fc mov -0x4(%rbp),%eax } 4004fa: 5d pop %rbp 4004fb: c3 retq 

正如你所看到的, c7 45 fc 42 42 42 42表示该值存储在生成的文件中。 事实上,当通过xxd查看二进制文件时就是这种情况:

 $ xxd a.out | grep 4242 00004f0: c745 fc42 4242 428b 45fc 5dc3 5548 89e5 .E.BBBB.E.].UH.. 

您可以在xxd代码片段中识别上述装配线。

由于a是隐式auto (即不是externstatic ),所以它被存储在调用栈帧中。

事实上,编译器可能会优化:在您的情况下,优化时,它可能会留在寄存器中(或者是不断的传播和不断折叠):无需为您的a分配一个调用堆栈槽

这当然是编译器,目标平台和操作系统的依赖。 对于GCC编译器,理解-fdump-tree-all内部表示(thru -fdump-tree-all或使用MELT探针 )并查看生成的汇编代码(使用-fverbose-asm -S -O

另请参阅这个答案 ,它提供了很多的参考。


Linux / x86-64上的GCC 4.8将你的函数编译成gcc -S -fverbose-asm -O

  .globl func .type func, @function func: .LFB0: .cfi_startproc movl $7, %eax #, ret .cfi_endproc .LFE0: .size func, .-func 

所以你可以看到,在你的特殊情况下没有额外的空间用于7 ,它直接存储在寄存器(在ABI约定中定义)的%eax中以保存它的返回结果。

7存储在机器代码中,在movl机器指令中。 func被执行时,7被加载到包含func返回结果的寄存器%eax中。

取决于示例代码,变量“a”进入调用堆栈,将函数调用信息(如程序计数器,返回地址等)与本地变量一起存储