很长一段时间以来,我一直被教导的方式是,当我运行程序时,立即进入堆栈的第一件事是 main 方法的堆栈帧。如果我从 main 中调用一个名为 foo() 的函数,那么一个堆栈帧就是局部变量(自动对象)的大小,并且参数也会被推送到堆栈上。
但是,我遇到了一些与此相矛盾的事情。我希望有人能澄清我的困惑或解释为什么真的没有任何矛盾。
第一个矛盾:
在 Bjarne Stroustrup 的《C++ 编程语言》第 3 版一书中,它在第 244 页上说,“每次在程序执行中遇到其声明时,都会创建一个命名的自动对象。” 如果这还不够清楚,在下一页它说,“每次控制线程通过局部变量的声明时,都会执行局部变量的构造函数。”
这是否意味着堆栈帧的总内存不是一次全部分配,而是在遇到变量声明时逐块分配?此外,这是否意味着如果由于 if 语句未遇到变量声明,则每次堆栈帧的大小可能不同?
第二个矛盾:
我在汇编中做了一些编码(具体来说是 ARM),我的课程被教授的方式是,当一个函数被调用时,我们立即使用寄存器并且从未将当前函数的任何局部变量推送到堆栈,除非算法无法使用有限数量的寄存器执行。即便如此,我们也只推送了剩余的变量。
这是否意味着在调用函数时,可能根本不会创建堆栈帧?这是否也意味着堆栈帧的大小可能由于寄存器的使用而不同?