我有一個簡單的彙編函數從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