C 局部变量如何存储在堆栈中?

C 局部变量如何存储在堆栈中?,c,C,众所周知,当我们声明局部变量时,它们被存储到堆栈中,即FILO。但我被要求画一个图表来显示这些变量是如何被推入堆栈的?我有点困惑,因为给出了示例代码: int giveMe_Red(int *xPos, int *yPos) { int count = 0; int *nextpos, ifTreped; int loc[8] = {0}; . . . . return count; } 有谁能帮助我理解每个变量是如何存储到内存中的,比如数组、指

众所周知,当我们声明局部变量时,它们被存储到堆栈中,即FILO。但我被要求画一个图表来显示这些变量是如何被推入堆栈的?我有点困惑,因为给出了示例代码:

int giveMe_Red(int *xPos, int *yPos)
{
   int count = 0;
   int *nextpos, ifTreped;
   int loc[8] = {0};
   .
   .
   .
   .
   return count;
}

有谁能帮助我理解每个变量是如何存储到内存中的,比如数组、指针等。比如说,0级中的“count”,然后是堆栈1级中的“*nextpos”或其他什么。如果存在递归,那么它们是如何存储的?

详细信息取决于处理器,但例如在x86中,所有变量的堆栈空间通常通过一次减法分配给
esp
。 标准的开场白是

push ebp                ; Save old base pointer
mov  ebp, esp           ; Mark current base pointer
sub  esp, stack_space   ; Allocate stack space
结语是

mov esp, ebp            ; Free stack space
pop ebp                 ; Reload old base pointer
ret                     ; Return to caller
在您的例子中,所需的空间(假设32位,并且这些都是局部变量)将是

  • 4个字节用于计数
  • 4对于
    nextPos
  • 4对于
    ifTreped
  • 4*8用于
    loc
    阵列
总共44个字节(+4个字节用于存储
ebp
)所需的空间

子esp之后,44
将有代码将
loc
的所有元素归零

编辑
在与gcc检查后,似乎分配的空间是48字节(不是44字节),不确定原因,但可能是由于堆栈对齐的原因。

Jonathan的回答是正确的,但没有回答您的问题。让我们举一个最简单的例子,假设没有优化,所有参数都在堆栈上传递,32位整数,32位地址,堆栈向下增长,调用方清理。 在给我打电话之前,我在某处得到了SP积分。为了能够从调用返回,您需要堆栈上的返回地址,即四个字节。两个int参数也在堆栈上,每个4字节,因此SP现在比其原始参数减少了12字节。一旦调用giveme_red,就需要更多的空间:四个字节用于计数,四个字节用于int指针,四个字节用于'iftreped',最后8倍于四个字节用于int数组。
为了能够实现递归(giveme_-red通过另一个函数直接或间接调用自身),giveme_-red需要设置一个新的堆栈框架来调用自身。重复上述相同的顺序。通常还有一个技巧,因为您需要能够访问本地变量和参数,另一个名为BP的寄存器通常会保存和恢复(在堆栈上)。如果你想了解更多Aho,Sethi,Ullman,Lam:编译器(龙之书)仍然是标准参考。

答案至少取决于编译器;它也可能取决于编译器选项。如果有VLA需要担心,它也会改变。