我似乎明白了编程语言设计中调用栈的概念。但是我找不到(可能是因为我搜索得不够努力)任何关于堆栈框架是什么的像样的解释。

所以我想请人用几句话给我解释一下。


当前回答

如果你理解栈很好,那么你将在程序理解记忆是如何工作的,如果你在程序理解记忆是如何工作的理解函数存储在程序如果你了解函数存储在程序你会理解递归函数是如何工作的,如果你理解递归函数是如何工作的,你会理解编译器是如何工作的,如果你理解编译器是如何工作的将是编译器和调试任何程序很容易

让我来解释一下stack的工作原理:

首先,你必须知道函数是如何在堆栈中表示的:

堆存储动态分配的值。 堆栈存储自动分配和删除值。

让我们用例子来理解:

def hello(x):
    if x==1:
        return "op"
    else:
        u=1
        e=12
        s=hello(x-1)
        e+=1
        print(s)
        print(x)
        u+=1
    return e

hello(4)

现在了解这个程序的部分内容:

现在让我们看看什么是堆栈以及堆栈部分是什么:

堆栈的分配:

Remember one thing: if any function's return condition gets satisfied, no matter it has loaded the local variables or not, it will immediately return from stack with it's stack frame. It means that whenever any recursive function get base condition satisfied and we put a return after base condition, the base condition will not wait to load local variables which are located in the “else” part of program. It will immediately return the current frame from the stack following which the next frame is now in the activation record.

在实践中可以看到:

块的回收:

所以现在只要函数遇到return语句,它就会从堆栈中删除当前帧。

当从堆栈返回时,值将以与它们在堆栈中分配的原始顺序相反的顺序返回。

其他回答

Stack frame is the packed information related to a function call. This information generally includes arguments passed to th function, local variables and where to return upon terminating. Activation record is another name for a stack frame. The layout of the stack frame is determined in the ABI by the manufacturer and every compiler supporting the ISA must conform to this standard, however layout scheme can be compiler dependent. Generally stack frame size is not limited but there is a concept called "red/protected zone" to allow system calls...etc to execute without interfering with a stack frame.

There is always a SP but on some ABIs (ARM's and PowerPC's for example) FP is optional. Arguments that needed to be placed onto the stack can be offsetted using the SP only. Whether a stack frame is generated for a function call or not depends on the type and number of arguments, local variables and how local variables are accessed generally. On most ISAs, first, registers are used and if there are more arguments than registers dedicated to pass arguments these are placed onto the stack (For example x86 ABI has 6 registers to pass integer arguments). Hence, sometimes, some functions do not need a stack frame to be placed on the stack, just the return address is pushed onto the stack.

“调用堆栈由堆栈帧组成……”——维基百科

堆栈帧是你放在堆栈上的东西。它们是包含要调用的子例程信息的数据结构。

堆栈帧是推入堆栈的数据帧。在调用堆栈的情况下,堆栈帧将表示函数调用及其参数数据。

如果我没记错的话,函数返回地址首先被压入堆栈,然后是局部变量的参数和空间。它们一起构成了“框架”,尽管这可能依赖于体系结构。处理器知道每个帧中有多少字节,并在帧被推入和弹出堆栈时相应地移动堆栈指针。

编辑:

高级调用栈和处理器调用栈之间有很大的区别。

When we talk about a processor's call stack, we are talking about working with addresses and values at the byte/word level in assembly or machine code. There are "call stacks" when talking about higher-level languages, but they are a debugging/runtime tool managed by the runtime environment so that you can log what went wrong with your program (at a high level). At this level, things like line numbers and method and class names are often known. By the time the processor gets the code, it has absolutely no concept of these things.

如果你理解栈很好,那么你将在程序理解记忆是如何工作的,如果你在程序理解记忆是如何工作的理解函数存储在程序如果你了解函数存储在程序你会理解递归函数是如何工作的,如果你理解递归函数是如何工作的,你会理解编译器是如何工作的,如果你理解编译器是如何工作的将是编译器和调试任何程序很容易

让我来解释一下stack的工作原理:

首先,你必须知道函数是如何在堆栈中表示的:

堆存储动态分配的值。 堆栈存储自动分配和删除值。

让我们用例子来理解:

def hello(x):
    if x==1:
        return "op"
    else:
        u=1
        e=12
        s=hello(x-1)
        e+=1
        print(s)
        print(x)
        u+=1
    return e

hello(4)

现在了解这个程序的部分内容:

现在让我们看看什么是堆栈以及堆栈部分是什么:

堆栈的分配:

Remember one thing: if any function's return condition gets satisfied, no matter it has loaded the local variables or not, it will immediately return from stack with it's stack frame. It means that whenever any recursive function get base condition satisfied and we put a return after base condition, the base condition will not wait to load local variables which are located in the “else” part of program. It will immediately return the current frame from the stack following which the next frame is now in the activation record.

在实践中可以看到:

块的回收:

所以现在只要函数遇到return语句,它就会从堆栈中删除当前帧。

当从堆栈返回时,值将以与它们在堆栈中分配的原始顺序相反的顺序返回。

快速总结一下。也许有人有更好的解释。

调用堆栈由一个或多个堆栈帧组成。每个堆栈帧对应于对一个函数或过程的调用,该函数或过程尚未以返回结束。

为了使用堆栈帧,线程保持两个指针,一个称为堆栈指针(SP),另一个称为帧指针(FP)。SP总是指向堆栈的“顶部”,而FP总是指向帧的“顶部”。此外,线程还维护一个程序计数器(PC),它指向下一条要执行的指令。

以下数据存储在堆栈中:

局部变量和临时变量; 当前指令的实际参数(过程、函数、 等等)。

关于堆栈的清理有不同的调用约定。