2017-05-07 1 views
0

私はPCASM本を知っていますが、私は1つのことを理解していません(これは私の誤解かもしれませんが、私はまだ低レベルのプログラミングには慣れていません)。 C呼び出し規約とりわけ、スタック x86 ASM:異なるコードセグメントへのリターンはどのように実装されていますか?

  • にリターンアドレスをプッシュしますが、サブルーチンを呼び出すために、スタック
  • 使用call命令、上に

    • プッシュ引数のようなものであるが、追加の引数を参照してくださいと言われていますリターンアドレスをポップ(必要であれば、その後、必要に応じて引数をポップ)と、呼び出し元のコード
    へジャンプするためにそれを使用する作業が終了ESP
  • コールretに一定のオフセット

    これまでのところ良い例ですが、リターンコードは単純にスタック上の4バイトであることがわかります。これにより、現在のコードセグメントのどこにでもジャンプすることができますが、サブルーチンが別のセグメントに戻る必要がある場合はどうなりますか?コードセグメントをリターンアドレスと同じ方法でスタックにプッシュしなければならない場合、サブルーチンの引数をどのように参照すればよいですか?

  • 答えて

    2

    retf命令は、セグメントとオフセットを含む "long return"を実行します。

    +0

    ASMで何かを書いていますが、実際にどこでも使用できます(返されるコードが同じセグメントに含まれているかどうかわからない場合)、デフォルトで 'retf'を使用する必要がありますか? – Etki

    +0

    絶対にありません。これは、関数が付随する "long call"を介して呼び出されたときにのみ使用できます。プッシュ/ポップされるバイト数は異なります。 –

    +2

    @Etkiリンクした文書で判断して保護モード(PM)でプログラミングしています。複数のパブリックユーザモードコードセグメントを実装しているOSはありません。セグメントを変更することは想定されていませんので、ファストコール/リターンを行う必要はありません。すべてのOSはフラットモデルを実装しています。このモデルでは、1つのセグメントが32ビットのアドレス空間すべてをカバーします。他のセグメントは必要ありません(分離はページングによって実現されます)。より遠いリターンは、特権間転送を必要とし、特権のないセグメントにのみ可能である場合、PMにもっと関与します。 Intelのマニュアルでは、これらすべてをカバーしています。 –

    関連する問題