4

有人告诉我,如果我将rsp其用作通用寄存器,操作系统可能会将寄存器转储到它在中断情况下指向的位置,从而导致有问题的行为。

这是真的吗,如果不是,如果我不需要堆栈,我可以rsp用作通用寄存器吗?

编辑:在用户空间中运行。

4

2 回答 2

5

如果发生中断,您不会搞砸吗?

那些在 DOS 中编程的人可能在这一点上对中断的可能性感到不安。通常,像这样重用堆栈指针是一个非常糟糕的主意,因为您不知道何时可能发生中断,而当一个中断发生时,CPU 会尽职尽责地将当前程序计数器和标志压入堆栈。如果您重用了 ESP,这将导致随机数据结构被丢弃。在这种环境中,ESP 必须始终指向有效且足够的堆栈空间来服务中断,并且当这不成立时,必须禁用中断。长时间禁用中断运行会降低系统响应能力(丢失中断和不良延迟),并且对于大型例程来说不实用。

但是,我们在这里以保护模式运行。

在 Win32 的用户空间中运行时,中断不会压入用户堆栈,而是压入内核堆栈。如果您考虑一下,则不可能使用用户堆栈。如果线程超出堆栈空间,或者甚至只是有一个无效堆栈,当 CPU 尝试推送 EIP 和 EFLAGS 时,它会出现页面错误,并且您不能在中断处理程序中出现页面错误。因此,调度程序可以在无堆栈例程运行时进行任意数量的上下文切换,并且任何指向 ESP 的数据结构都不会受到影响。

来自http://www.virtualdub.org/blog/pivot/entry.php?id=85

于 2014-03-06T00:43:14.060 回答
0

是的,您可以在非常可控的情况下,但实际上只使用 SSE2 和/或 MMX。


相关:写在ESP下面是否有效?讨论 Windows 中可以异步使用 32 位代码中的堆栈指针的东西。使用无效的堆栈指针,这些东西会崩溃而不是踩到它下面的空间。(或者如果指向可写内存,则将其用作堆栈空间。)

在 GNU/Linux 中,信号处理程序可以异步使用用户空间堆栈指针,但您可以使用sigaltstack/SA_ONSTACK为它们使用备用堆栈。


另请注意,x86-64 保证 SSE2。如果您已经使用了所有 xmm0..15 (SSE) 和 mm0..7 (MMX),通常只需要考虑使用 RSP 作为第 16 个通用寄存器。

对于没有 MMX 的 CPU,将 ESP 用作 32 位 DSP 代码中的第 8 个通用寄存器有时是有意义的;这就是为什么可以在 virtualdub 过滤器的上下文中找到关于它的讨论。

它在 64 位代码中通常没有意义,因为您总是有 16 个 128 位 SIMD 寄存器(以及在它们上使用的 SIMD 指令),以及两倍多的非堆栈指针整数寄存器。以及 8 个 64 位 mmx 寄存器,或 8 个 80 位 x87 寄存器,但您想使用它们。在大多数调用约定中,这些寄存器中的大多数都是调用破坏的,但是您不能在 RSP 不指向堆栈的情况下进行函数调用。

于 2020-10-06T21:41:58.440 回答