我可以使用 rsp 作为通用寄存器吗?

kva*_*nck 4 assembly x86-64 cpu-registers stack-pointer

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

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

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

kva*_*nck 6

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

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

然而,我们在这里运行在保护模式下。

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

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

  • 使用“sigaltstack”设置堆栈,然后在安装处理程序时使用“sigaction”并在标志中指定“SA_ONSTACK”。 (3认同)
  • 这是事实,但还要记住,信号处理程序确实使用用户堆栈(正如 Brett Hale 在该问题中提到的那样)。需要处理的两个选项是阻止所有信号,或为任何未阻止的信号设置自定义堆栈。 (2认同)