C中变量名如何存储在内存中? [英] How are variable names stored in memory in C?

查看:26
本文介绍了C中变量名如何存储在内存中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C 中,假设您有一个名为 variable_name 的变量.假设它位于 0xaaaaaaaa,在那个内存地址,你有整数 123.也就是说,variable_name 包含 123.

In C, let's say you have a variable called variable_name. Let's say it's located at 0xaaaaaaaa, and at that memory address, you have the integer 123. So in other words, variable_name contains 123.

我正在寻找有关短语variable_name is located at 0xaaaaaaaa"的说明.编译器如何识别字符串variable_name"与该特定内存地址相关联?字符串variable_name"是否存储在内存中的某处?编译器是否只是将 variable_name 替换为 0xaaaaaaaa ,如果是这样,它是否不必使用内存来进行替换?

I'm looking for clarification around the phrasing "variable_name is located at 0xaaaaaaaa". How does the compiler recognize that the string "variable_name" is associated with that particular memory address? Is the string "variable_name" stored somewhere in memory? Does the compiler just substitute variable_name for 0xaaaaaaaa whenever it sees it, and if so, wouldn't it have to use memory in order to make that substitution?

推荐答案

在编译器运行后变量名不再存在(除非在共享库或调试符号中导出全局变量等特殊情况).整个编译过程旨在采用源代码表示的那些符号名称和算法,并将它们转换为本地机器指令.所以是的,如果你有一个全局的 variable_name,并且编译器和链接器决定把它放在 0xaaaaaaaa,那么它在代码中的任何地方,它都会通过那个地址.

Variable names don't exist anymore after the compiler runs (barring special cases like exported globals in shared libraries or debug symbols). The entire act of compilation is intended to take those symbolic names and algorithms represented by your source code and turn them into native machine instructions. So yes, if you have a global variable_name, and compiler and linker decide to put it at 0xaaaaaaaa, then wherever it is used in the code, it will just be accessed via that address.

所以回答你的字面问题:

So to answer your literal questions:

编译器如何识别字符串variable_name"与该特定内存地址相关联?

How does the compiler recognize that the string "variable_name" is associated with that particular memory address?

工具链(编译器和链接器)共同为变量分配内存位置.跟踪所有引用是编译器的工作,链接器稍后会放入正确的地址.

The toolchain (compiler & linker) work together to assign a memory location for the variable. It's the compiler's job to keep track of all the references, and linker puts in the right addresses later.

字符串 "variable_name" 是否存储在内存中的某处?

Is the string "variable_name" stored somewhere in memory?

仅在编译器运行时.

编译器是否只是在看到 0xaaaaaaaa 时用 variable_name 替换它,如果是这样,它是否不必使用内存来进行替换?

Does the compiler just substitute variable_name for 0xaaaaaaaa whenever it sees it, and if so, wouldn't it have to use memory in order to make that substitution?

是的,几乎就是这样,除了它是链接器的两阶段工作.是的,它使用内存,但它是编译器的内存,而不是程序运行时的任何内存.

Yes, that's pretty much what happens, except it's a two-stage job with the linker. And yes, it uses memory, but it's the compiler's memory, not anything at runtime for your program.

一个例子可能会帮助你理解.让我们试试这个程序:

An example might help you understand. Let's try out this program:

int x = 12;

int main(void)
{
    return x;
}

很简单,对吧?行.让我们把这个程序,编译一下,看看反汇编:

Pretty straightforward, right? OK. Let's take this program, and compile it and look at the disassembly:

$ cc -Wall -Werror -Wextra -O3    example.c   -o example
$ otool -tV example
example:
(__TEXT,__text) section
_main:
0000000100000f60    pushq   %rbp
0000000100000f61    movq    %rsp,%rbp
0000000100000f64    movl    0x00000096(%rip),%eax
0000000100000f6a    popq    %rbp
0000000100000f6b    ret

看到那行 movl 了吗?它正在获取全局变量(在这种情况下以指令指针相对方式).不再提及 x.

See that movl line? It's grabbing the global variable (in an instruction-pointer relative way, in this case). No more mention of x.

现在让我们让它更复杂一些并添加一个局部变量:

Now let's make it a bit more complicated and add a local variable:

int x = 12;

int main(void)
{  
    volatile int y = 4;
    return x + y;
}

这个程序的反汇编是:

(__TEXT,__text) section
_main:
0000000100000f60    pushq   %rbp
0000000100000f61    movq    %rsp,%rbp
0000000100000f64    movl    $0x00000004,0xfc(%rbp)
0000000100000f6b    movl    0x0000008f(%rip),%eax
0000000100000f71    addl    0xfc(%rbp),%eax
0000000100000f74    popq    %rbp
0000000100000f75    ret

现在有两个 movl 指令和一个 addl 指令.您可以看到第一个 movl 正在初始化 y,它决定将在堆栈上(基指针 - 4).然后下一个movl把全局的x放入寄存器eaxaddl加上y 到那个值.但是正如您所看到的,文字 xy 字符串不再存在.它们对(程序员)来说很方便,但计算机在执行时当然不会关心它们.

Now there are two movl instructions and an addl instruction. You can see that the first movl is initializing y, which it's decided will be on the stack (base pointer - 4). Then the next movl gets the global x into a register eax, and the addl adds y to that value. But as you can see, the literal x and y strings don't exist anymore. They were conveniences for you, the programmer, but the computer certainly doesn't care about them at execution time.

这篇关于C中变量名如何存储在内存中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆