[英]Where are global variables located in the activation record for C?
在 C 中,每个 function 都有一个在堆栈帧上分配的激活记录。 局部变量分配在它们自己的函数的激活记录中。 那么,全局变量是怎么回事呢? 它们分配在哪里?
例如
#include <stdio.h>
int a;
void v()
{a= 2;
int b;
b++;
}
main()
{
int f;
printf("\n%d",a);
v();
}
-----Activation record----
-------------------
-------------------
activation record for main
-------------------
int f
-------------------
-------------------
activation record of v
--------------------
int a
--------------------
int b
--------------------
---------------
根据激活记录逻辑,变量x
存储在哪里?
在 C 中,每个 function 都有一个在堆栈帧上分配的激活记录。
没有。 但是,编译器通常是这样解决的。 至少如果您没有激活任何优化。
首先,C 标准根本没有提到堆栈。 所以这个问题的答案将是关于它在实践中通常是如何解决的。
通常它们位于数据段或 bss 段中。 典型的布局如下所示:
Stack - Grows down towards the heap. Used for local variables.
-----
...
...
...
----
Heap - Grows up towards the stack. Used for dynamically allocated memory.
----
BSS - Uninitialized data. Used for uninitialized global and static variables.
----
Data - Initialized data.
----
Text - Runnable code
在 C 中,每个 function 都有一个在堆栈帧上分配的激活记录。
错了,优化编译器可能不会这样做(并且gcc -O3 -flto
不会,在 Linux / x86-64 和最近的Z32D8B233E3C58A262A0B75872Z297 上)。 它将内联一些函数。 一些本地变量只保存在一些处理器寄存器中(因此没有 memory 位置)。 阅读有关寄存器分配的信息,例如在Dragon Book或其他一些关于编译器的教科书中。 注意自动变量。 另请注意,您甚至不需要计算机来运行 C 程序(教学 C 的好方法是让课堂游戏成为计算机;您可以用铅笔在纸上运行 Z0D61F8370CAD1D412F87B84D14 程序)。
全局变量通常不在调用堆栈(保存调用帧或激活记录)上。 它们可能位于数据段中(并且可以完全优化)。
C11 规范不需要任何调用堆栈。 通过阅读n1570进行检查。 一些实现不使用任何调用堆栈(或激活记录)。 请注意crt0调用您的main
。
阅读链接器和加载器了解更多信息。 另请阅读有关操作系统的教科书。
在 Linux 上,尝试cat /proc/self/maps
以了解运行该cat
命令的进程的虚拟地址空间; 参见过程(5)
使用 Linux 查看由gcc -O2 -fverbose-asm -S
生成的汇编代码。 阅读有关调用 GCC的信息。
另请参阅此答案。
在 Linux 上,在可执行文件或object 文件( ELF格式)上使用nm(1) 、 readelf(1) 、 objdump(1 )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.