堆栈的行为(向上或向下)取决于应用程序二进制接口(ABI)以及调用堆栈(即激活记录)的组织方式。
程序在其整个生命周期中都必须与其他程序(例如OS)进行通信。ABI确定一个程序如何与另一个程序进行通信。
不同体系结构的堆栈可以以任何一种方式增长,但是对于体系结构而言,它将是一致的。请检查此Wiki链接。但是,堆栈的增长是由该架构的ABI决定的。
例如,如果您使用MIPS ABI,则调用堆栈的定义如下。
让我们考虑函数“ fn1”调用“ fn2”。现在,由“ fn2”看到的堆栈框架如下:
direction of | |
growth of +---------------------------------+
stack | Parameters passed by fn1(caller)|
from higher addr.| |
to lower addr. | Direction of growth is opposite |
| | to direction of stack growth |
| +---------------------------------+ <-- SP on entry to fn2
| | Return address from fn2(callee) |
V +---------------------------------+
| Callee saved registers being |
| used in the callee function |
+---------------------------------+
| Local variables of fn2 |
|(Direction of growth of frame is |
| same as direction of growth of |
| stack) |
+---------------------------------+
| Arguments to functions called |
| by fn2 |
+---------------------------------+ <- Current SP after stack
frame is allocated
现在您可以看到堆栈向下生长。因此,如果将变量分配给函数的局部框架,则变量的地址实际上会向下增长。编译器可以决定内存分配的变量顺序。(在您的情况下,可以是'q'或's'是首先分配的堆栈内存。但是,通常,编译器按照变量声明的顺序进行堆栈内存分配)。
但是在数组的情况下,分配只有一个指针,需要分配的内存实际上将由单个指针指向。内存需要是连续的数组。因此,尽管堆栈向下增长,但对于阵列,堆栈却向上增长。