【问题标题】:What does it mean that decrementing the stack pointer reserves space on the stack?递减堆栈指针在堆栈上保留空间是什么意思?
【发布时间】:2015-11-10 16:48:34
【问题描述】:

在这种情况下,“保留”究竟是什么意思?递减堆栈指针如何保留堆栈上的空间?调整堆栈指针寄存器有副作用吗?

“保留空间”听起来像内存分配,但堆栈的内存通常是固定的并预先分配,所以我不认为这就是它的意思。

我认为这只是意味着我们告诉其他人不要使用我们的堆栈空间,而其他人只是读取堆栈指针寄存器并且按照惯例知道它不应该破坏任何高于此的内容。如果是这样,那另一个人又是谁?后续函数调用?操作系统?

【问题讨论】:

  • 你的第三段是对的。按照惯例,任何低于堆栈指针(假设它向下增长)都是公平的游戏。
  • @SevaAlekseyev 公平游戏适合谁使用?职能?操作系统?还有谁?如果您想充实您的答案评论,请继续发布答案。 ;)
  • 您的函数正在调用的函数。请注意,您的函数不应该像进入时那样破坏堆栈指针下方的任何内容。您的函数将调用的函数将遵循相同的约定。此外,中断处理程序。
  • 了解 push 和 pop 的确切作用 stackoverflow.com/a/33583134/895245 以及 C 函数编译成的内容。然后就清楚了。
  • @SevaAlekseyev:在现代操作系统中,IRQ 处理程序使用单独的内核堆栈(出于安全原因:用户进程的另一个线程可以修改内核函数正在使用的堆栈内存!!)。但是,signal 处理程序可以随时异步使用堆栈指针下方的空间。 (在 Linux/Mac (SysV) 64 位 ABI 中,rsp 下面有一个 128B 的“红色区域”,可以防止信号处理程序或其他任何东西的异步破坏,因此不需要更多的叶子函数可以避免不得不调整堆栈指针,节省几条指令。)

标签: assembly x86 x86-64 cpu-registers stack-frame


【解决方案1】:

堆栈指针现在有点低的事实已经保留了空间。递归调用的函数等将(希望)通过不写入以这种方式保留的内存来尊重保留(没有什么真正阻止它们,但如果它们这样做了,它们就会被破坏)。

原则上可以写入未以这种方式分配的堆栈空间,但由于它是一个通常不会完成的免费操作(特别是它可能不会,也可能不会在函数调用中幸存下来,这可能很容易分配它并在上面写,如果它不是红色区域的一部分,信号处理程序会使用这个空间),最大的例外是叶子函数中 x64(不是 Windows)上的红色区域。

一种分配,它是在固定大小的缓冲区内分配,但一切也是如此,最终无论如何你只能分配这么多的内存。它只是更加有限。

【讨论】:

  • 好点。我应该指定动态内存分配。
  • @Praxeolitic 很好,它也是动态的,它是在运行时调用函数时完成的,而不是在编译时固定的
  • 另外,堆栈大小可能不会预先固定,操作系统可能会根据需要按需增长。
  • 问题不在于函数调用。这是信号处理程序的异步破坏,使堆栈指针下方(或红色区域下方)的空间不安全用于任何东西。甚至叶函数也需要保留它们使用的任何空间。 (红色区域算作已保留。)另外请注意,只有 SysV ABI 有红色区域。 64 位 Windows ABI 没有。
  • @harold:是的,我在评论中所说的并没有真正反映我的想法。我认为信号处理程序可以出现并在任何时间异步修改rsp 以下的内存这一事实很重要。否则叶子函数就不必保留内存。 OP 的最后一段是询问可以发生什么并使用堆栈指针下方的内存,所以是的,答案是进一步的函数调用和“操作系统”(以信号处理程序的形式)。
猜你喜欢
  • 2011-05-09
  • 1970-01-01
  • 2023-03-09
  • 2019-11-23
  • 2010-09-07
  • 2010-09-15
  • 2011-05-30
  • 1970-01-01
相关资源
最近更新 更多