【问题标题】:Is it safe to use the stack below esp?使用 esp 下面的堆栈是否安全?
【发布时间】:2009-04-22 19:05:56
【问题描述】:

我有一个从 c 程序调用的简单汇编函数,我必须使用需要内存操作数的指令 (FIDIV)。

将值移动到[esp - 2] 并在下一条指令中使用它是否安全,或者以这种方式使用堆栈永远不安全?

我知道有很多解决方法,我真的不再需要这个了,所以现在只是好奇。

【问题讨论】:

  • 附注 - 如果您在汇编例程中使用 FPU 寄存器,系统或 C 编译器可能希望您保存 FPU 的状态并在返回之前恢复它。

标签: assembly intel


【解决方案1】:

使用这样的偏移量肯定会在任何时候线程上的任何操作需要再次触及堆栈时将数据暴露给损坏。这可能在中断、APC、上下文切换、异常等期间发生。您要做的是实际在堆栈上保留空间并保存指向它的指针。

sub esp, 4        ; Allways move it 4 byte increments. x64 may need 8 bytes
mov eax, esp      ; EAX points to your 4 byte buffer
add esp, 4        ; Restore allocation.

当然如果你只需要几个字节,push指令会快很多

push eax
mov  eax, esp     ; EAX points to a buffer properly alligned to system 

【讨论】:

  • 函数返回前别忘了从栈中弹出!
【解决方案2】:

这并不安全 - 堆栈的一部分可能用于上下文切换、中断以及您的线程几乎不了解或无法控制的其他事情。

【讨论】:

  • 我要补充一点,只要您存储堆栈的内容,留在程序中并在离开之前恢复它们,它就是安全的。但这在多线程环境中仍然很危险。
  • 这是不正确的。上下文切换和中断发生在内核堆栈上。
  • @Zifre - 这取决于平台/环境。如果你在 Windows 上,你可能是对的 - 我认为这仍然是一种非常脆弱且容易出错的做法,任何试图在我正在开发的软件上使用它的人都必须能够证明它的合理性和侧身。
  • 更不用说内核有理由期望能够使用用户模式堆栈的那部分,如果它出于某种原因倾向于使用(正如 Paul Alexander 所指出的,用户模式 ​​APC 可能在 Windows 上执行此操作)。
【解决方案3】:

有点。只要您不调用另一个函数,或者(在 Unix 上)调用信号,它就是安全的。不过,它会非常容易坏,所以我不会这样做。可以先从 esp 中减去,然后使用该空间。

不必担心中断或上下文切换;这些发生在内核堆栈上。如果您可以通过更改堆栈来搞砸这些,那么内核崩溃将是微不足道的。

【讨论】:

    猜你喜欢
    • 2016-11-03
    • 2011-10-29
    • 2020-08-11
    • 1970-01-01
    • 2015-06-17
    • 2015-05-24
    • 2019-02-14
    • 2016-06-05
    相关资源
    最近更新 更多