简体   繁体   English

C 的激活记录中的全局变量位于何处?

[英]Where are global variables located in the activation record for C?

In C, each function has an activation record which is allocated on a stack frame.在 C 中,每个 function 都有一个在堆栈帧上分配的激活记录。 Local variables are allocated in their own function's activation record.局部变量分配在它们自己的函数的激活记录中。 So, what is the case with global variables?那么,全局变量是怎么回事呢? Where are they allocated?它们分配在哪里?

For example例如

#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
--------------------
---------------

Where is variable x stored according to the activation record logic?根据激活记录逻辑,变量x存储在哪里?

In C each function has an activation record which is allocated on a stack frame.在 C 中,每个 function 都有一个在堆栈帧上分配的激活记录。

Nope.没有。 However, this is how it is usually solved by the compiler.但是,编译器通常是这样解决的。 At least if you have not activated any optimizations.至少如果您没有激活任何优化。

Firstly, the C standard does not say anything about a stack at all.首先,C 标准根本没有提到堆栈。 So an answer to this will be about how it's usually solved in practice.所以这个问题的答案将是关于它在实践中通常是如何解决的。

And usually they are in the data segment or bss segment.通常它们位于数据段或 bss 段中。 A typical layout looks like this:典型的布局如下所示:

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

In C each function has an activation record which is allocated on a stack frame.在 C 中,每个 function 都有一个在堆栈帧上分配的激活记录。

Wrong , an optimizing compiler might not do that (and gcc -O3 -flto won't, on Linux / x86-64 with a recent GCC ).了,优化编译器可能不会这样做(并且gcc -O3 -flto不会,在 Linux / x86-64 和最近的Z32D8B233E3C58A262A0B75872Z297 上)。 It will inline some functions.它将内联一些函数。 Some locals are only kept in some processor registers (so have no memory location).一些本地变量只保存在一些处理器寄存器中(因此没有 memory 位置)。 Read about register allocation , eg in the Dragon Book or some other textbook about compilers.阅读有关寄存器分配的信息,例如在Dragon Book或其他一些关于编译器的教科书中。 Be aware of automatic variables .注意自动变量 Be also aware that you don't even need a computer to run a C program (a good way of teaching C is to have the classroom play being a computer; and you could run a C program on paper with a pencil).另请注意,您甚至不需要计算机来运行 C 程序(教学 C 的好方法是让课堂游戏成为计算机;您可以用铅笔在纸上运行 Z0D61F8370CAD1D412F87B84D14 程序)。

The globals are usually not in practice on the call stack (which hold call frames or activation records).全局变量通常不在调用堆栈(保存调用帧或激活记录)上。 They might sit in the data segment (and could be optimized out entirely).它们可能位于数据段中(并且可以完全优化)。

The C11 specification does not require any call stack. C11 规范不需要任何调用堆栈。 Check by reading n1570 .通过阅读n1570进行检查。 Some implementations don't use any call stack (or activation records).一些实现不使用任何调用堆栈(或激活记录)。 Be aware of the crt0 calling your main .请注意crt0调用您的main

Read linkers and loaders for more.阅读链接器和加载器了解更多信息。 Read also a textbook about operating systems .另请阅读有关操作系统的教科书

On Linux, try cat /proc/self/maps to understand the virtual address space of the process running that cat command;在 Linux 上,尝试cat /proc/self/maps以了解运行该cat命令的进程虚拟地址空间 see proc(5)参见过程(5)

Look into the assembler code generated by gcc -O2 -fverbose-asm -S , using Linux.使用 Linux 查看由gcc -O2 -fverbose-asm -S生成的汇编代码。 Read about invoking GCC .阅读有关调用 GCC的信息。

See also this answer .另请参阅此答案

On Linux, play with nm(1) , readelf(1) , objdump(1) on your executable or object file (in ELF format).在 Linux 上,在可执行文件object 文件ELF格式)上使用nm(1)readelf(1)objdump(1 )。

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

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