本地和其他变量类型的地址存储在哪里?

Where are the addresses of local and other variable types stored?

有人问我这个问题,我不太确定答案。我知道局部变量的值(内容)在堆栈上,而那些分配在堆上(在 C/C++ 语言中)。但是:

1- 那些局部变量的地址存储在哪里?程序如何知道应该在堆栈的哪个位置查找每个局部变量?这些引用(每个变量的地址)是否保存在数据段中?其他变量类型(全局,指针,...)的地址如何

2- 在处理局部变量时,程序直接(不使用 pop/push)read/write 到堆栈段中的不同地址是否正确?

  1. 编译器将跟踪每个参数和局部变量相对于堆栈顶部的位置。并且如果可能的话,编译器将为 "important" 变量(例如循环计数器)使用寄存器——它会使用统计每个变量被使用了多少次来查看哪些是 "hot"(使用很多)哪些是 "cold"(用得不多)。

    请注意,"addresses of local variables" 并不总是适用。寄存器没有(直接)地址 [TI TMS9900 处理器和其他一些处理器除外,其中寄存器和内存的线条略微模糊]。

    编译器会知道每个东西在哪里——这就是编译器所做的——就像它知道哪个变量存储在数据部分的什么地方一样。具体如何做到这一点是一本小书的主题。现在,只需相信编译器会这样做。

  2. 是的,现在几乎所有的处理器都允许从堆栈 + 偏移量读取和写入(其中偏移量通常为负,因此在堆栈的更下方,因为堆栈通常向零增长)。

    尽管堆栈有时算作 "data segment",但在现代机器上它通常是它自己的内存部分 - 如果您有多个线程,每个线程都会有自己的堆栈。

首先,对于协议,我们只需要注意这两个问题的答案都取决于编译器的实现,而不是由语言标准(C 和 C++)决定的。


Where are the addresses of those local variables stored?

符号(函数和变量的名称)在编译期间被翻译成地址,也就是说,它们不存储在执行程序的内存中的任何地方:

  • 函数地址在可执行映像的代码段中

    它们在整个程序执行过程中是不变的

  • 静态and/or全局变量的地址在可执行映像的数据段中

    它们在整个程序执行过程中是不变的

  • 非静态局部变量的地址在可执行映像的堆栈中

    每次调用声明这些变量的函数时它们可能不同


Am I right that programs directly (not using pop/push) read/write to different addresses in stack segment when dealing with local variables?

取决于您的平台(底层硬件架构 + 指定编译器)。

回复 #2:"the stack" 属于 stack frames,不是单独的局部变量。虽然有时会压入和弹出单个值(例如、return 地址),但局部变量通常通过简单地调整堆栈指针一次性创建。 "creates" 堆栈上的一个区域没有存储任何特定值(这就是为什么未初始化的变量可能有任何值),然后使用堆栈指针的偏移量来查找各个变量。

另见 a similar CS SE question