在Aleph One 的 Smashing The Stack For Fun And Profit中找到了很好的解释。提取最相关的部分。
/------------------\ lower
| | memory
| Text | addresses
| |
|------------------|
| (Initialized) |
| Data |
| (Uninitialized) |
|------------------|
| |
| Stack | higher
| | memory
\------------------/ addresses
Fig. 1 Process Memory Regions
[...]
The stack consists of logical stack frames that are pushed when calling a
function and popped when returning. A stack frame contains the parameters to
a function, its local variables, and the data necessary to recover the
previous stack frame, including the value of the instruction pointer at the
time of the function call.
Depending on the implementation the stack will either grow down (towards
lower memory addresses), or up. In our examples we'll use a stack that grows
down. This is the way the stack grows on many computers including the Intel,
Motorola, SPARC and MIPS processors.
[...]
Let us see what the stack looks like in a simple example:
example1.c:
------------------------------------------------------------------------------
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
}
void main() {
function(1,2,3);
}
------------------------------------------------------------------------------
[...]
With that in mind our stack looks like this when function() is called (each
space represents a byte):
bottom of top of
memory memory
buffer2 buffer1 sfp ret a b c
<------ [ ][ ][ ][ ][ ][ ][ ]
top of bottom of
stack stack
如您所见,新的(局部)变量被压入堆栈顶部。根据架构的设计,堆栈会向更高的内存地址或更低的内存地址增长,在您的情况下是后者。
从 C 语言规范的角度来看,随后分配的变量的内存位置顺序是未指定的。因此,这取决于...