为什么功能激活记录需要动态链接?(用静态范围的语言)

Yuv*_*mon 5 c programming-languages

我读到动态链接指向前一个激活记录,因此在动态范围编程语言中是有意义的.但是在静态范围编程语言中,为什么访问链接(指向一个较低嵌套级别的功能的激活记录)是不够的?特别是在C中 - 为什么不需要访问链接?为什么需要动态链接?

a3f*_*a3f 4

我将使用我更熟悉的术语:

\n
\n

激活记录:堆栈帧

\n

动态链接:[保存]帧指针

\n
\n

所以,我将你的问题解释为:为什么需要帧指针?[1]

\n

不需要帧指针。

\n

某些编译器(例如 Green Hills C++、带有 -O2 的 GCC)通常不生成它,或者可以要求不生成它(MSVC、GCC)。

\n

也就是说,它当然有它的好处:

\n
    \n
  • 轻松遍历调用堆栈:生成堆栈跟踪就像遍历帧指针形成头的链表一样简单。使堆栈跟踪和调试器的实现变得更加容易。

    \n
  • \n
  • 更容易的代码生成:可以通过索引帧指针而不是不断变化的堆栈指针来引用堆栈变量。堆栈指针随着每次压入/弹出而变化,帧指针在函数内保持不变(在序言/结尾之间)

    \n
  • \n
  • 如果出现问题,可以使用帧指针来完成堆栈展开。这就是 Borland\xe2\x80\x99s 结构化异常处理 (SEH) 的工作原理。

    \n
  • \n
  • 简化堆栈管理setjmp(3):特别是alloca(3)C99-VLA 的实现可能(并且通常)依赖于它。

    \n
  • \n
\n

缺点:

\n
    \n
  • 寄存器使用:x86 只有 8 个通用寄存器。其中之一需要完全专用于保存帧指针。
  • \n
  • 开销:为每个函数生成序言/尾声。
  • \n
\n

但正如您所注意到的,编译器可以生成完美的代码,而无需维护帧指针。

\n
\n

[1] 如果不是这个意思,请详细说明。

\n