● 関数リファレンス
最後に実行された命令に関する情報の取得
void __stdcall floatex_get_lastcmd(PFPU_LASTCMD *pdest);
引数
引数名 | 意味 |
pdest | 結果を格納する領域の先頭アドレス |
戻り値
無し
説明
ラスト命令ポインタ、オペランドポインタ、オペコードレジスタ等の情報を取得し、pdest が指す FPU_LASTCMD 構造体の領域へ格納します。
FPU_LASTCMD 構造体.
typedef struct {
unsigned long instruction_pointer;
unsigned long code_seg;
unsigned long operand_adr;
unsigned long data_seg;
unsigned long opecode;
unsigned long reserved[3];
} FPU_LASTCMD,*PFPU_LASTCMD;
この構造体は floatex.h 内で定義されています。
メンバ名 | 意味 |
instruction_pointer | ラスト命令ポインタ |
code_seg | コードセグメント |
operand_adr | オペランドアドレス |
data_seg | データセグメント |
opecode | オペコード |
reserved | 予約 |
例外の処理やフラグのクリアは行われません。必要がある場合は他の関数や処理の組み合わせで行ってください。
この関数は、汎用レジスタの内容を変えません。また、EFLAGS の内容を保存します。
最後に実行した FPU 命令を確認する実験(2)
#include <stdio.h>
#include "floatex.h"
__declspec(naked) unsigned long get_nextadr(void)
{
_asm{
mov eax,[esp]
ret
}
}
void main(void)
{
unsigned long adr;
floatex_loadcw(FEX_PC_64 | FEX_RC_NEAR);
__try{
_asm{
fld1
call get_nextadr
faddp st,st ; この命令が、最後に実行されたものになります
mov adr,eax
}
floatex_raise_exception(FEX_STAT_IE,0);
}
__except(1){
FPU_LASTCMD cmdinf;
floatex_get_lastcmd(&cmdinf);
printf("\n");
printf(" 実際のアドレス:0x%08x\n",adr);
printf("ラスト命令ポインタ:0x%08x\n\n",cmdinf.instruction_pointer);
/*
"faddp st,st" は 11011110 : 11000000b
オペコードレジスタのフォーマットにすると 0x6c0
(11011110 11000000b & 7ffh)
*/
printf(" オペコード:0x%03x\n",cmdinf.opecode);
}
floatex_reset();
}
/*
その他の命令のオペコードについては 「Intel 64 and IA-32 Architectures
Software Developer's Manual Volume 2B」の「B.12 FLOATING-POINT INSTRUCTION
FORMATS AND ENCODINGS」を参照してください。
*/