2009-04-22 66 views
4

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

将值移到[esp - 2]并将它用于下一条指令是安全的还是以这种方式使用堆栈是不安全的?

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

+0

备注 - 如果在汇编例程中使用FPU寄存器,系统或C编译器可能会希望保存FPU的状态并在返回之前将其恢复。 – 2009-04-22 20:31:53

回答

6

使用这样的偏移量将会明确地暴露出数据在任何时候线程上的任何操作需要再次触摸堆栈时发生损坏。这可能发生在中断,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 
4

这是不安全的 - 该堆栈的一部分可能用于上下文切换,中断以及其他线程很少或不知道或无法控制的其他事情。

+0

我想补充一点,只要你存储了堆栈的内容,保留在你的程序中并在离开之前恢复。但是这在多线程环境中仍然很危险。 – schnaader 2009-04-22 19:14:35

+0

这是不正确的。上下文切换和中断发生在内核堆栈上。 – Zifre 2009-04-22 19:22:30

1

。只要你不调用另一个函数,或者(在Unix上)有一个被调用的信号,它是安全的。不过,这很容易破坏,所以我不会这样做。可以,但只需从esp首先减去,然后使用该空间。

不要不得不担心中断或上下文切换;这些发生在内核堆栈上。如果你可以通过更改堆栈来解决这些问题,那么崩溃内核将是微不足道的。