2009-04-22 258 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首先減去,然後使用該空間。

不要不得不擔心中斷或上下文切換;這些發生在內核堆棧上。如果你可以通過更改堆棧來解決這些問題,那麼崩潰內核將是微不足道的。