解释一个堆栈帧的概念概括地说解释一个堆栈帧的概念概括地说(Explain the concept o

2019-05-13 10:49发布

看来我得在编程语言设计的调用堆栈的想法。 但我找不到(也许,我只是不搜索够硬)什么堆栈帧是什么像样的解释。

所以我想问有人解释给我几句。

Answer 1:

堆栈帧是数据帧的是被压入堆栈。 在调用栈的情况下,一个堆栈帧将代表一个函数调用和它的参数的数据。

如果我没有记错,函数返回地址被压入堆栈,然后再参数和空间的局部变量。 他们一起做“框架,”虽然这可能是体系结构相关。 处理器知道有多少字节中的每个帧并进入相应的帧被推动并弹出堆栈的堆栈指针。

编辑:

有上级呼叫栈和处理器的调用堆栈之间有很大的区别。

当我们谈论处理器的调用堆栈,我们正在谈论与在组装或机器代码的字节/字的水平地址和值工作。 谈到更高层次的语言时,有“调用栈”,但他们是由运行时环境管理的调试/运行工具,这样你就可以登录了什么问题与您的程序(高级别)。 在这个层面上,像行号和方法和类的名称往往是已知的。 由处理器获得的代码的时候,就绝对没有这些东西的概念。



Answer 2:

如果你了解栈很好,那么你就会明白内存的程序是如何工作的,如果你了解内存的程序是如何运作的,你会明白如何器功能存储在程序,如果您了解如何在程序功能商店,你将了解如何递归函数的工作原理,如果您了解函数是如何递归的作品你会明白如何编译工作,如果你了解编译器是如何工作的你的心将作品的编译器,你会很容易调试任何程序

让我来解释一下堆是如何工作的:

首先,你必须知道函数栈如何店:

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

让我们以实例理解:

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)

现在明白这个程序的部分:

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

堆栈分配:

记住一点,如果任何功能得到“回报”不管它加载了他的所有本地可变因素或任何会立即从栈将自己的堆栈帧返回。 这意味着当任何递归函数得到基本条件,我们把基础条件,使基础条件之后,返回不会等待加载均位于局部变量“其他”项目的一部分,它会立即从栈如果一个帧返回当前帧和现在返回下一帧的活动记录。 看到这个现实:

块的释放:

所以,现在每当一个函数发现return语句删除它从堆栈当前帧。

而从堆栈返回值将返回的顺序相反的顺序,他们在分配的堆栈。

这些都是非常简短的说明,如果你想了解更多深约栈和双递归读过两年后本博客:



Answer 3:

一个快速的收官之作。 也许有人有一个更好的解释。

调用堆栈是由1个或几个许多栈帧。 每个堆栈帧对应于一个还没有终止的返回的功能或过程的调用。

要使用的堆栈帧,线程保持两个指针,一个被称为堆栈指针(SP),并且另一种是所谓的帧指针(FP)。 SP总是指向堆栈的“顶”,和FP总是指向该帧的“顶部”。 此外,该线程也维护指向将要执行的下一个指令的程序计数器(PC)。

被存储在栈上执行以下操作:本地变量和临时,当前指令的实际参数(过程,函数等)

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



Answer 4:

“调用栈由栈帧的......” - 维基百科

堆栈帧是你把堆栈上的东西。 它们是包含有关子程序调用信息的数据结构。



Answer 5:

程序员可能对堆栈帧的问题不是在一个广义的术语(这是在栈中的烧毛实体提供只是一个函数调用,并保持返回地址,参数和局部变量),但在狭义上-当术语stack frames是在编译器选项上下文中提及。

无论是问题的作者意味着与否,而是从编译器选项方面堆栈帧的概念是一个非常重要的问题,不属于对方回复在这里。

例如,微软的Visual Studio 2015年的C / C ++编译器必须与以下选项stack frames

  • / Oy公司(帧指针省略)

GCC有以下几点:

  • 。-fomit帧指针(不要保存在一个寄存器中的帧指针不需要一个功能,这可以避免指令保护,设置和恢复帧指针;它还使许多功能提供一个额外的寄存器)

英特尔C ++编译器有以下几种:

  • -fomit帧指针(确定是否EBP被用作优化的通用寄存器)

它具有以下别名:

  • / Oy公司

德尔福具有以下命令行选项:

  • - $ W +(生成堆栈帧)

在特定意义上说,从编译器的角度来看,一个堆栈帧仅仅是常规 ,是推动锚堆栈的进入和退出代码 -也可用于调试和异常处理。 调试工具可以扫描堆栈数据,并使用这些锚回溯,而定位call sites的堆栈,即他们已经分层调用的顺序显示的功能名称。 对于英特尔架构,这是push ebp; mov ebp, esp push ebp; mov ebp, espenter入境, mov esp, ebp; pop ebp mov esp, ebp; pop ebpleave出境。

这就是为什么要了解一个程序员什么堆栈帧是当它涉及到的编译器选项中是非常重要的 - 因为编译器可以控制是否生成此代码或没有。

在一些情况下,堆栈帧(该例程进入和退出代码)可以由编译器被省略,并且该变量将被直接经由堆栈指针(SP / ESP / RSP),而不是方便基指针(BP /访问ESP / RSP)。 堆栈帧,例如省略条件:

  • 该函数是叶功能(即,不调用其他功能的终端实体);
  • 有没有尝试/ finally或try /除外或类似的结构,即无例外被使用;
  • 没有例程调用堆栈上传出参数;
  • 所述函数没有参数;
  • 函数没有联汇编代码;
  • 等等...

省略堆栈帧(进入和退出的代码,该例程)可以使代码更小和更快,但它也可能不利地影响调试器来回溯堆栈中的数据,并把它显示给程序员的能力。 这些是编译选项决定在哪些条件下的函数应具有入口和出口的代码,例如:(a)总是,(b)中从未,(c)中当需要时(指定的条件)。



Answer 6:

堆栈帧相关的函数调用打包的信息。 这些信息一般包括传递给TH功能,局部变量并在终止时返回的参数。 活动记录是一个堆栈帧的另一个名字。 堆栈帧的布局在ABI由制造商确定,并且每一个编译器支持ISA必须符合这个标准,但是布局方案可以是依赖于编译器。 一般来说堆栈帧大小没有限制,但有一个叫做“红/保护区”,允许系统调用的概念......等等,而不带有堆栈帧的干扰来执行。

总有一个SP,但是,一些ABI(ARM公司和PowerPC的举例)FP是可选的。 需要加以放置到堆参数可以仅使用SP被抵消。 是否为函数调用中产生或不堆栈帧取决于类型和参数,局部变量和局部变量是如何通常访问号码。 在大多数的ISA中,首先,寄存器用于,如果有更多的参数比专用于传递参数寄存器这些被放置到堆栈(例如ABI 86具有6个寄存器传递整数参数)。 因此,有时,某些功能不需要堆栈帧被放置在栈中,只是返回地址被压入堆栈。



文章来源: Explain the concept of a stack frame in a nutshell
标签: callstack