程序如何在堆栈中查找全局变量?

时间:2018-09-11 14:23:55

标签: assembly x86 binary stack global-variables

据我所知,当我声明全局变量int my_var;时,
它位于<bss>(未初始化的全局数据)或<.rodata>(初始化全局数据)部分的 固定地址 中。

ex)

int my_var;          // <= It is at <.bss> section
int my_var = 0x1337; // <= It is at <.rodata> section

因此,程序可以使用 固定地址找到那些 static 值。

问题 :但是,我听说位于<stack>的全局变量。

C运行时启动初始化全局变量:__environprogram_invocation_name
并且它们位于<stack> ....中,这意味着其地址是不确定的。

问题 。程序如何在stack(非固定区域)内找到全局变量?

2 个答案:

答案 0 :(得分:2)

__ environ等不在堆栈中;它们是普通的全局变量,它们是指向堆栈中位置的指针(即,其值为地址的变量)。初始程序环境,参数等位于堆栈中的事实是实现细节。可以很容易地在堆中或在其他区域中分配它们,以适合运行时。

唯一重要的是运行时启动程序和操作系统就可以在哪里找到它们达成共识。

[回应评论] 下面的程序应说明:

#include <stdio.h>
extern char **environ;

int main() {
 int x;
 printf("&envrion  = %p\n", &environ);
 printf("environ   = %p\n", environ);
 printf("*environ  = %p [%s]\n", *environ, *environ);
 printf("&x        = %p\n", &x);
 return 0;
}

在我的系统上运行(cc -static x.c; ./a.out)时,会生成:

&envrion  = 0x6bbda8
environ   = 0x7ffdd6edb3e8
*environ  = 0x7ffdd6edb9a2 [CLUTTER_IM_MODULE=xim]
&x        = 0x7ffdd6edb2a4

请注意&environ的地址与environ,* environ和&x的地址有很大不同。这是因为后者在堆栈中,而环境本身不在堆栈中。

答案 1 :(得分:0)

您能否提供示例或参考书来指示存储在堆栈中的全局变量?

堆栈的重点是根据(时间)变量的范围分配内存,因此将堆栈用于“始终有效”变量是没有意义的(正如您所说,还有另一个部分)。

对于您的示例(int my_var = 0x1337;),可能不会在只读节上分配初始化变量,因为这并不意味着它有时不会被修改(编译器的决定除外)。

  

问题。程序如何在堆栈(非固定区域)内找到全局变量?

堆栈是一个LIFO队列,其中的指针指示最后的位置,每个时间变量都获得一个地址(创建时在堆栈边界内),该地址指示其位置,直到被销毁(超出范围)并且堆栈指针被更新。但是环境变量没有存储在堆栈上,而是位于堆栈上方:https://www.thegeekstuff.com/2012/03/linux-processes-memory-layout/