私はプログラムでこの命令を持っています:
FSTENV (28-BYTE) PTR SS:[ESP-1C]
それは何をするためのものか?
どのレジスタを使用して更新しますか?
ありがとうございました!
浮動小数点環境を格納します。これには、現在の制御ワード、ステータスワード、タグワード、命令ポインター、およびオペランドポインターが含まれます。それらはメモリ内の構造体に格納されます。16ビットモードでは、その構造は14バイトです。32ビットモードでは、28バイトです。64ビットモードで使用できるかどうかはまったくわかりません(64ビットモードでは代わりにSSEがほとんど使用されます)[編集:32ビットモードと64ビットモードで同じように動作するようです。]
コプロセッサーの現在の状態が変わるとは思わない[編集:おっと-FP例外をマスクしますが、ほとんどの人は最初からマスクを解除しないので...]-しかし、 、それはあなたがそれを保存してfldenv
いたときの状態に復元します。fstenv
ジェリー棺の答えは正しいです。
疑問に思われる場合(28-BYTE) PTR SS:[ESP-1C]
:
これはFP環境が格納される有効なアドレスであり、コマンドの28バイトバージョンを指定し、スタックセグメントのスタックポインタの下の28(0x1c)バイトを指します。
検索エンジンを使用して見つけたIntelの公式説明を追加するだけです。
説明
現在のFPU動作環境を、宛先オペランドで指定されたメモリ位置に保存してから、すべての浮動小数点例外をマスクします。FPU動作環境は、FPU制御ワード、ステータスワード、タグワード、命令ポインタ、データポインタ、および最後のオペコードで構成されます。IA-32インテル®アーキテクチャー・ソフトウェア開発者マニュアル、第1巻の図7-13から7-16は、プロセッサーの動作モード(保護または実数)と現在のオペランドに応じた、保管環境のメモリー内のレイアウトを示しています。 -サイズ属性(16ビットまたは32ビット)。仮想8086モードでは、リアルモードのレイアウトが使用されます。
FSTENV命令は、FPU環境を保存する前に、保留中のマスクされていない浮動小数点例外をチェックして処理します。FNSTENV命令はそうではありません。保存された画像は、命令ストリーム内のFSTENV/FNSTENV命令に先行するすべての浮動小数点命令が実行された後のFPUの状態を反映しています。
これらの命令は、FPU命令とデータポインタへのアクセスを提供するため、例外ハンドラによってよく使用されます。通常、環境はスタックに保存されます。環境を保存した後にすべての例外をマスクすると、浮動小数点例外が例外ハンドラーに割り込むのを防ぐことができます。インテル®アーキテクチャーの互換性
Pentium®またはIntel486™プロセッサをMS-DOS*オペレーティングシステム互換モードで動作させる場合、保留中のFPU例外を処理するために、実行前にFNSTENV命令が中断される可能性があります(異常な状況下で)。これらの状況の説明については、IA-32インテル®アーキテクチャーソフトウェア開発者マニュアル第1巻の付録Dの「待機しないFPU命令がウィンドウでFPU割り込みを取得する可能性がある」というタイトルのセクションを参照してください。Pentium Proプロセッサでは、この方法でFNSTENV命令を中断することはできません。
手術
DEST [FPUControlWord)<-FPUControlWord;
DEST [FPUStatusWord)<-FPUStatusWord;
DEST [FPUTagWord)<-FPUTagWord;
DEST [FPUDataPointer)<-FPUDataPointer;
DEST [FPUInstructionPointer)<-FPUInstructionPointer;
DEST [FPULastInstructionOpcode)<-FPULastInstructionOpcode;
影響を受けるFPUフラグ
C0、C1、C2、およびC3は未定義です。
浮動小数点の例外
なし。
プロテクトモードの例外
GP(0)-宛先が書き込み不可能なセグメントにある場合。メモリオペランドの実効アドレスがCS、DS、ES、FS、またはGSセグメントの制限外にある場合。DS、ES、FS、またはGSレジスタがメモリへのアクセスに使用され、ヌルセグメントセレクタが含まれている場合。
SS(0)-メモリオペランドの実効アドレスがSSセグメント制限外の場合。
NM-CR0のEMまたはTSが設定されます。
PF(fault-code)-ページフォールトが発生した場合。
AC(0)-現在の特権レベルが3のときに、アライメントチェックが有効で、アライメントされていないメモリ参照が行われた場合。リアルアドレスモードの例外
GP-メモリオペランドの実効アドレスがCS、DS、ES、FS、またはGSセグメントの制限外の場合。
SS-メモリオペランドの実効アドレスがSSセグメント制限外の場合。
NM-CR0のEMまたはTSが設定されます。仮想-8086モードの例外
GP(0)-メモリオペランドの実効アドレスがCS、DS、ES、FS、またはGSセグメントの制限外の場合。
SS(0)-メモリオペランドの実効アドレスがSSセグメント制限外の場合。
NM-CR0のEMまたはTSが設定されます。
PF(fault-code)-ページフォールトが発生した場合。
AC(0)-アライメントチェックが有効で、アライメントされていないメモリ参照が行われた場合。
完全を期すために、FSTENV
/FNSTENV
命令が生成するメモリレイアウトを次に示します。これは、x86-64"Long 64-bit Mode"
でもx86でも同じ"32 bit compatibility mode"
です(x86-64でプレフィックスを付加しない限り66h
)。
この扱いにくいIntelドキュメントを引用すると、次のレイアウトになります。
(ところで、上の画像も「ロングモード」と名付けられているはずです。)
したがって、実際のテストを長い64ビットモードで実行すると、次のようになります。
FNSTENV
そして、次のコンテキスト状態で命令の直後に中断します。
返されるメモリのレイアウトは次のとおりです。
これは、私が隠すつもりはありませんが、非常に奇妙です。(切り刻まれたRIPレジスタから奇妙な外観のオペコードまで何でも。)しかし、レガシーの理由から、それはまだサポートされていると思います。
良いニュースは、現代のx64コードをコーディングするときに、これらの古風なx87FPU命令の用途が今日残っていないことです。その場合は、浮動小数点のニーズに合わせて、XMM0
スルーレジスタとそれに関連する命令を確実に使用する必要があります。XMM15
別のアプローチで質問に答えたいと思います。
FSTENVは「実際の」命令ではありません。
「FNSTENV」オペコードを検索すると、より幸運になる可能性があります。
エンコーディングを詳しく調べます(Intel SDMから)。
FSTENV 9B D9 /6
FNSTENV D9 /6
その主要な「9B」を見ますか?
それは本当に「FNSTENV」の前に付けられた「FWAIT」です。
したがって、「FSTENV」は、他の多くの命令と同様に、ほとんどのアセンブラおよび逆アセンブラによって理解される単なる規則です。
Intelのマニュアルにはこの特殊性が記載されていますが、100%の場合に正確であると期待すべきではなく、そのような詳細が省略されている場合があります。
FSTENV /FNSTENV-ストアx87FPU環境(Vol。2A 3-393)
アセンブラはFSTENV命令に対して2つの命令(FWAIT命令の後にFNSTENV命令が続く )を発行し、プロセッサはこれらの各命令を個別に実行します。これらの命令のいずれかに対して例外が生成された場合、saveEIPは例外の原因となった命令を指します。
そのような「特別な」指示はたくさんあります。
たとえば、x86にNOPがいくつあるかに驚かれるかもしれませんが、通常は他の命令のエイリアスになります。
Intel XEDは、いくつかの理由で苦労するのに便利です。
Go asmにはx86.csvと呼ばれるものがあり、Intel SDM形式でx86命令をリストしますが、追加情報が含まれる場合もあります。
「FSTENV」のgrepを実行すると、「pseudo」タグが関連付けられていることがわかります。
x86.v0.2.csvは、特に新しい拡張機能からの一部の命令を見逃す可能性があることに注意してください(ただし、これはv0.3で修正される予定です)。