我有一个简单的汇编函数从c程序调用,我必须使用需要内存操作数的指令(FIDIV
)。使用esp下的堆栈安全吗?
将值移到[esp - 2]
并将它用于下一条指令是安全的还是以这种方式使用堆栈是不安全的?
我知道有很多解决方法,我真的不需要这个了,所以现在它只是好奇心。
我有一个简单的汇编函数从c程序调用,我必须使用需要内存操作数的指令(FIDIV
)。使用esp下的堆栈安全吗?
将值移到[esp - 2]
并将它用于下一条指令是安全的还是以这种方式使用堆栈是不安全的?
我知道有很多解决方法,我真的不需要这个了,所以现在它只是好奇心。
使用这样的偏移量将会明确地暴露出数据在任何时候线程上的任何操作需要再次触摸堆栈时发生损坏。这可能发生在中断,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 eax
mov eax, esp ; EAX points to a buffer properly alligned to system
。只要你不调用另一个函数,或者(在Unix上)有一个被调用的信号,它是安全的。不过,这很容易破坏,所以我不会这样做。可以,但只需从esp首先减去,然后使用该空间。
你不要不得不担心中断或上下文切换;这些发生在内核堆栈上。如果你可以通过更改堆栈来解决这些问题,那么崩溃内核将是微不足道的。
备注 - 如果在汇编例程中使用FPU寄存器,系统或C编译器可能会希望保存FPU的状态并在返回之前将其恢复。 – 2009-04-22 20:31:53