Windows 2000向けQueryUnbiasedInterruptTime

_declspec(dllexport) _declspec(naked)
void WINAPI QueryUnbiasedInterruptTime(PULONGLONG pos){
// (c)2017 BlackWingCat
    _asm{
        push        ebp
        mov         ebp,esp
        sub esp,0x14

        lea eax,[ebp-0xc]
        push eax
        call DWORD PTR [QueryPerformanceFrequency]
       
        lea eax,[ebp-0x14]
        push eax
        call DWORD PTR [QueryPerformanceCounter]

        wait
        fnstcw      word ptr [ebp-2]
        wait

        fild qword ptr [ebp-0x14]
        and dword ptr [ebp-0x14],0
        mov dword ptr [ebp-0x14+4],0x416312d0
        fmul qword ptr [ebp-0x14]
        fild qword ptr [ebp-0xc]
        fdivp st(1),st
        mov ecx,[ebp+8]

        mov         ax,word ptr [ebp-2]
        or          ah,0Ch
        mov         word ptr [ebp-4],ax
        fldcw       word ptr [ebp-4]
        fistp       qword ptr [ecx]

        fldcw       word ptr [ebp-2]
        leave
        retn 4
    }
}

FPUとパフォーマンスカウンタを使って100nsec 精度のQueryUnbiasedInterruptTime をエミュレートする関数作ってみた・ω・

次の拡張カーネルに実装予定

FPUプログラミング初めてやってみたら、関数ループさせるとなぜかスタックオーバーフローが発生してめちゃくちゃ悩んだ。
単に、FPUのインデックスレジスタがステータスレジスタに格納されていて、そこがあふれると計算できなくなるので
fnstcw / fldcw で保存・復元する必要があったようだ・ω・

時刻・時間のしくみ - .mjtの日記復帰計画

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です