Intelチップ上のAPERF/MPERFカウンターを読み取るプログラムを作成しました(http://www.intel.com/content/dam/doc/manual/64-ia-32-architectures-software-developer-volの2ページ) -3b-part-2-manual.pdf)。
これらのカウンターは、readmsr / writemsr命令を介して読み取り/書き込み可能であり、現在、Windows 7のデバイスドライバーを介して一定の間隔で読み取りを行っています。カウンターは64ビットであり、プロセッサークロックごとにほぼ増分します。 dは非常に長い時間でオーバーフローすることを期待していますが、カウンターを読み取ると、別のプログラムによってリセットされているかのように値がジャンプします。
どのプログラムがカウンターをリセットするかを追跡する方法はありますか?他の何かが間違った値を読み取る原因になっている可能性がありますか?私が使用している関連するアセンブリと対応するC関数を以下に添付します。rdmsrからの64ビットの結果はeax:edxに保存されるため、r_xレジスタに数値がないことを確認するために、コマンドを複数回実行してすべてをチェックします。
C:
long long test1, test2, test3, test4;
test1 = TST1();
test2 = TST2();
test3 = TST3();
test4 = TST4();
status = RtlStringCbPrintfA(buffer, sizeof(buffer), "Value: %llu %llu %llu %llu\n", test1, test2, test3, test4);
組み立て:
;;;;;;;;;;;;;;;;;;;
PUBLIC TST1
TST1 proc
mov ecx, 231 ; 0xE7
rdmsr
ret ; returns rax
TST1 endp
;;;;;;;;;;;;;;;;;;;
PUBLIC TST2
TST2 proc
mov ecx, 231 ; 0xE7
rdmsr
mov rax, rbx
ret ; returns rax
TST2 endp
;;;;;;;;;;;;;;;;;;;
PUBLIC TST3
TST3 proc
mov ecx, 231 ; 0xE7
rdmsr
mov rax, rcx
ret ; returns rax
TST3 endp
;;;;;;;;;;;;;;;;;;;
PUBLIC TST4
TST4 proc
mov ecx, 231 ; 0xE7
rdmsr
mov rax, rdx
ret ; returns rax
TST4 endp
印刷される結果は次のようになりますが、変更されるレジスタはraxレジスタのみであり、単調に増加することはありません(ジャンプする可能性があります)。
Value: 312664 37 231 0
Value: 252576 37 231 0
Value: 1051857 37 231 0