7

私は、Borland C++ を使用して、longjmps を使用して複数のスタックを切り替える、16 ビット用の C で書かれた古いコードをいくつか持っています。malloc を実行して新しいスタックを作成し、インライン アセンブラを使用して、malloc された領域のアドレスのセグメントとオフセットに SS および SP レジスタを設定します。Win32 に変換したいのですが、2 つの命令を ESP を設定する 1 つの命令に置き換える必要があるようです。2 つの命令は CLI/STI のペアで囲まれていましたが、Win32 ではこれらは「特権命令」を与えるため、ここでは省略しています。私は Windows に関してはまったく無知なので、最初のテスト ケースが機能したことにかなり驚きました。ですから、私のやや漠然とした質問は、私がやっていることは a) 危険すぎて続行できないのか、b) コードを追加すればうまくいくのか、ここの専門家に尋ねることです。特定の予防策を講じるなど?後者の場合、何を追加する必要があり、それについてどこで確認できますか? SS、EBX など、他のレジスタについて心配する必要はありますか? 私は使っている最適化はありません...人々が私に与えることができるヒントをありがとう。

4

5 に答える 5

9

CLI/STI の削除は、動作環境の違いにより引き続き機能します。

16 ビット DOS では、割り込みが発生する可能性があり、この割り込みは最初は同じスタックで実行されます。操作の途中で中断された場合、sp ではなく ss のみを更新したため、割り込みがクラッシュする可能性があります。

Windows およびその他の最新の環境では、各ユーザー モード スレッドは独自のスタックを取得します。何らかの理由でスレッドが中断された場合、そのスタックとコンテキストは安全に保存されます。スレッドとスタックで実行されている他の何かについて心配する必要はありません。この場合の cli/sti は、OS によってすでに保護されているものから保護します。

グレッグが述べたように、Windows でこのようにスタックを交換する安全でサポートされている方法は、CreateFiber/SwitchToFiber です。これには、コンテキスト全体を変更するという副作用があるため、スタックを切り替えるだけではありません。

これは本当にあなたが何をしたいのかという問題を提起します。多くの場合、スタックの切り替えは、16 ビット DOS では 64k だった限られたスタック スペースを利用することになります。Windows では、1 MB のスタックがあり、さらに大きく割り当てることができます。なぜスタックを切り替えようとしているのですか?

于 2009-05-15T01:46:20.057 に答える
5

これを行う最も安全な方法は、スレッドやファイバーなどの公式の Win32 マルチプログラミング構造にコードを移植することです。ファイバーは非常に軽量なマルチスタック パラダイムを提供し、アプリケーションに適しているように思えます。

Win32 にファイバーがあるのはなぜですか? 記事も興味深い読み物です。

于 2009-05-15T01:42:20.393 に答える
0

これをユーザーモードで実行しましたが、問題はないようです。cli / stiは必要ありません。これらの命令は、コード内のその時点での割り込みを防ぐだけです。これは、私たちに伝えた限られた情報からは不要なはずです。

于 2009-05-15T01:54:03.250 に答える
0

スタックをジャンプすると、引数またはスタック常駐変数がホースになることを忘れないでください。

于 2009-05-15T06:19:45.670 に答える
0

Bert HubertのMtaskerをご覧ください。単純な協調マルチタスクを実行します。これを使用してコードを移植するのは簡単かもしれません。

于 2009-05-15T06:01:53.093 に答える