● 関数リファレンス

最後に実行された命令に関する情報の取得

    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」を参照してください。
*/