2010-11-24 41 views
2

我们知道,局部变量位于堆栈上。但是,他们的订单是什么?他们是按照他们声明的顺序排列的吗?这意味着第一个声明的变量被安排在堆栈的较高地址(堆栈增长到较低地址)?作为一个例子:编译器如何在堆栈中安排局部变量?

void foo(){ 
int iArray[4]; 
int iVar; 
} 

在堆栈,如随后在本地变量 - iArrayiVar和布置?

alt text

+2

您是在谈论一个特定的操作系统,处理器架构和编译器组合,还是您一般都想知道?我相信堆栈中局部变量的位置是一个编译器细节,可能会有很大差异。 – martineno 2010-11-24 08:57:46

+0

我也认为这是编译器依赖。 – remainn 2010-11-24 09:08:05

回答

1

最简单的实现可以非常容易地预测各种变量最终会在堆栈中出现的位置。但是,这些实现还允许某些安全问题(主要是溢出缓冲区预测额外数据将覆盖什么,允许注入shellcode)。由于堆栈的布局是在大多数基于堆栈的语言中实现定义的(从技术上讲,许多这样的语言不要求使用堆栈,而是具有易于用堆栈实现的语义) ,编译器编写者已经竭尽全力地致力于make it hard to predict the stack layout at runtime

4

没有规则,你可以依靠的人。除非您开始优化代码,否则绝大多数编译器都将使用声明顺序。

启用优化可能会导致堆栈空间重用,重新排序局部变量或甚至将变量移动到CPU寄存器,因此它们不再显示在堆栈上。

[编辑]在某些系统上,堆栈增长到更大的地址。所以它从0x1000开始,下一个地址是0x1001,而不是以0xffff开始,下一个地址是0xfffe。

+0

为了防止堆栈溢出,一些编译器可能会在正常局部变量下安排数组,尽管它们的声明顺序如此。 – remainn 2010-11-24 09:04:02

4

只有关闭优化功能!

一旦优化器获得您的代码,所有投注都关闭。积极优化的常见策略如下:

  • 如果该变量从未使用过或只是另一个变量的副本,请将其放下。
  • 按照使用顺序对变量重新排序。如果您的应用程序正在使用交换空间,并且还有助于缓存利用率(在某些计算机上),这将非常有用
  • 将经常使用的变量移动到寄存器中。常见的有32个可爱的genreral通用寄存器的风险机器。英特尔在其8款单用途寄存器上并不常见。
  • 更改数据类型。例如将小整数转换为整数常常加速寄存器加载和缓存。
  • 重排序存储以最小化松弛字节。例如char a,double b,char c,int d可以重新排序为double b,int d,char a,char c,从而节省10个字节。