2009-04-22 6 views
4

私はcプログラムから呼び出される単純なアセンブリ関数を持っているので、メモリオペランドを必要とする命令(FIDIV)を使用する必要があります。espの下でスタックを使用するのは安全ですか?

[esp - 2]に値を移動して次の命令で使用するのは安全ですか、それともそのようにスタックを使用することは決して安全ですか?

私は多くの回避策があることを知っています。私は実際にこれをもう必要としないので、今は好奇心です。

+0

サイドノート - アセンブリルーチンでFPUレジスタを使用している場合、システムまたはCコンパイラは、FPUの状態を保存してから復帰する前に復元することを期待している場合があります。 –

答えて

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 
+0

関数から戻る前にスタックからポップすることを忘れないでください! – Benoit

4

スタックのその部分は、コンテキストスイッチ、割り込み、スレッドの知識や制御がほとんどないその他のものに使用できます。

+0

私は、スタックの内容を保存し、プログラムの中に留まり、それを離れる前に復元する限り、安全だと付け加えたい。しかし、これはマルチスレッド環境では依然として危険です。 – schnaader

+0

これは正しくありません。コンテキストスイッチや割り込みは、カーネルスタック上で発生します。 – Zifre

+1

@Zifre - プラットフォーム/環境によって異なります。もしあなたがWindows上にいるなら、正しいかもしれません - 私が脆弱で、エラーを起こしやすいと考えている練習は、私が取り組んでいるソフトウェアでそれを使ってみようとする人は、それを正当化できなければならない横向きです。 –

1

ソートです。別の関数を呼び出さない限り、または(Unix上で)シグナルが呼び出されても安全です。それでも、中断するのは非常に簡単なので、私はやりません。 espを最初に差し引いて、そのスペースを使用しても構いません。

You は、割り込みやコンテキストスイッチについて心配する必要はありません。それらはカーネルスタック上で発生します。スタックを変更してそれらを混乱させることができれば、カーネルをクラッシュさせることは自明です。

関連する問題