2009-05-15 12 views
7

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

+1

これは非常に興味深い質問です!私はちょうど16ビットのC++のプロではないので、どうしてあなたはスタックをまったく入れ替えるのですか? –

+1

古い16ビットコードであることを考えれば、ある種の自家製繊維の実装だと思います。私は、システムによって提供されるスレッドが非常に重いため、このようなことをしたコンソールビデオゲームをいくつか知っています。 – Charlie

+0

はい、優れたレスポンスが多数見つかったので、これは自家用繊維の実装です(私の最初のフローベースプログラミングの実装はPC上にあります)。 16ビットバージョンは、実際には米国の大企業での制作作業に使用されていました。私は、Win32にファイバーの実装があることに気づいていませんでした.Greg Hewgillが引用した記事を読んでいます。あなた方全員に感謝します! –

答えて

9

CLI/STIの削除は、動作環境の違いによっても機能します。

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

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

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

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

+0

これは、私の最初のFlow-Based Programmingの実装です。私はWin32にファイバーの実装があることに気づいていませんでしたが、私のコードをFibersに変換するのは非常に難しいかもしれません - でも、Greg Hewgill氏が引用した記事を読んでいます。あなた方全員に感謝します! –

5

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

Why does Win32 even have fibers?の記事も面白いです。

+0

その記事の記事の1つは、「スタックベースを切り替えてもスタックの制限を更新しない、例外ハンドラリストを切り替えない、FPの状態を入れ替えることを忘れています」と述べています。繊維が私のためにそれらの事を見ていると仮定すると、私は繊維の間でlongjmpsを行うことができますか?私は自分自身を見てみたいと思ったら、彼らはどれだけ複雑で、どこでそれらを見つけることができますか?どうも。 –

+1

私はすでに私の答えの繊維に関するMSDNのドキュメントにリンクしています。あなたの質問のほとんどに答えなければならない完全な関数参照があります。私は、あなたが "繊維間の長い間隙"を試みるべきではないと思っていますが、代わりにSwitchToFiberのような公式の機能を使用してください。 –

+0

ありがとう、グレッグ。ドキュメンテーションは少し面倒だったようですが、私はそれを掘り起こします。 –

0

これはユーザーモードで行っており、問題はないようです。あなたはcli/stiを必要としません。これらの命令は、コード内のその時点での割り込みを防ぎます。

0

Bert HubertによるMtaskerをご覧ください。シンプルな協調マルチタスキングを行いますが、これを使用してコードを移植するのは簡単です。

0

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