● 関数リファレンス
FPU 環境の保存
void __stdcall floatex_fpusave(void *pdest);
引数
引数名 | 意味 |
pdest | 結果を格納する領域の先頭アドレス |
戻り値
無し
説明
レジスタスタックを含む FPU 環境を pdest が指す領域に保存した後で、コントロールワード以外の FPU 情報をリセットします。
pdest が指す領域は、128 バイト以上の大きさが必要です。保存したデータは floatex_fpuload で読み込み、FPU に再設定する事ができますが、設定の一部を変更する目的には使用できません。
領域の型は、どのようなものでもかまいませんが、次の構造体にすると、内容を参照する事ができます。
FPU 環境構造体.
typedef struct {
unsigned long cw;
unsigned long stw;
unsigned long tw;
unsigned long instruction_pointer;
unsigned short code_seg;
unsigned short opecode;
unsigned long operand_adr;
unsigned short data_seg;
unsigned short reserved1;
FLOATEX reg[8];
unsigned long reserved2[5];
} FPU_ENV,*PFPU_ENV;
この構造体は floatex.h 内で定義されています。
メンバ名 | 意味 |
cw | コントロールワード |
stw | ステータスワード |
tw | タグワード |
instruction_pointer | ラスト命令ポインタ |
code_seg | コードセグメント |
opecode | オペコード |
operand_adr | オペランドアドレス |
data_seg | データセグメント |
reserved1 | 予約 |
reg | レジスタスタック |
reserved2 | 予約 |
この関数は、汎用レジスタの内容を変えません。また、EFLAGS の内容を保存します。
内容を参照するプログラム例:最後に実行した FPU 命令を確認する実験(1)
#include <stdio.h>
#include "floatex.h"
void main(void)
{
FPU_ENV env;
unsigned long adr;
_asm{
fld1
lea eax,cmd_address
mov adr,eax
cmd_address:
fstp st ; この命令が、最後に実行されたものになります
}
floatex_fpusave(&env);
printf("\n");
printf(" 実際のアドレス:0x%08x\n",adr);
printf("ラスト命令ポインタ:0x%08x\n\n",env.instruction_pointer);
/*
"fstp st" は 11011 101 : 11011000b
オペコードレジスタのフォーマットにすると 0x5d8
(11011101 11011000b & 7ffh)
*/
printf(" オペコード:0x%03x\n",env.opecode);
}
/*
応用時の注意:
__try ブロック内で、このプログラムのように、ラベルによるアドレス取得を行
う場合、古いコンパイラでは C2705 が発生する事があります。
その場合は、アドレスの取得をラベルよりも後ろの位置で行ってください。
位置の変更が困難な場合は、floatex_get_lastcmd のリファレンスにあるプログ
ラム例の方法も検討してみてください。
*/