C语言中变量名是如何存储在内存中的?

2024-05-08

在 C 中,假设你有一个名为variable_name。假设它位于0xaaaaaaaa,在该内存地址处,您有整数 123。换句话说,variable_name包含 123 个。

我正在寻找有关措辞的澄清“variable_name位于0xaaaaaaaa”。编译器如何识别字符串“variable_name”与该特定内存地址关联?字符串“variable_name”是否存储在内存中的某个位置?编译器是否只是替换variable_name for 0xaaaaaaaa每当它看到它时,如果是这样,它是否不需要使用内存来进行替换?


编译器运行后,变量名称不再存在(除非共享库或调试符号中导出的全局变量等特殊情况)。整个编译过程的目的是获取源代码所表示的符号名称和算法,并将它们转换为本机机器指令。所以是的,如果你有一个全球variable_name,编译器和链接器决定将其放在0xaaaaaaaa,那么无论在代码中使用它,都只能通过该地址访问它。

所以回答你的字面问题:

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

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

是字符串吗"variable_name"存储在内存中的某个地方?

仅当compiler在跑。

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

是的,这几乎就是所发生的情况,只不过它是链接器的两阶段工作。是的,它使用内存,但它是编译器的内存,而不是程序运行时的任何内容。

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

int x = 12;

int main(void)
{
    return x;
}

很简单,对吧?好的。让我们来编译这个程序并看看反汇编:

$ 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.

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

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存入寄存器eax,以及addl adds y到那个值。但正如你所看到的,字面意思是x and y字符串不再存在。它们为人们提供了便利you,程序员,但计算机在执行时肯定不关心他们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言中变量名是如何存储在内存中的? 的相关文章

随机推荐