<Home> → <weekly making now!> → <weekly making now! (99.11.13)>
この章は DOS、Windows 9x、Windows NT を対象としています。 |
巷では Hardware を認識したり Benchmark を取ったりするソフトウェアが人気を博しているようです。有名所で言うと以下のソフトウェアです。
これらのソフトウェアはどのようにして CPU を認識、識別をしているのでしょうか?もちろん、Windows の API にも CPU の種類を返してくれる function はあります。しかし、標準の API はかなり poor な機能しか持ってなく、os の version によってもマチマチなので使用されていないのが普通です。実は CPU には自分自身を判別するための命令(opcode)を用意しています。
それが CPUID です。
実際に CPUID を呼び出して CPU を判別してみましょう。
Windows 付属のユーティリティ Debug.exe(ってよりMS-DOS 3.x から付属していてWindows
9x はもとより Windows NT にもあるんだよね>Debug.exe)でも出来ない訳ではないのですが、色々面倒くさいので以下のユーティリティを使って説明します。
それでは早速実習に入ります。
D:\>exdeb <Enter> |
いきなり終了してしまいました (^^;。
「q」は終了するコマンドです。覚えて置きましょう。
それでは早速 cpuid を実行してみましょう。
ちなみに私の使用している CPU は Intel Pentium II (233MHz)です。言い忘れましたが、念のためすべての
program を閉じておいた方が良いでしょう。cpuid をサポートしていない cpu
だととてつもない事が、、、(^^;
一応、チェックする方法は下記に示してあります。
D:\>exdeb <Enter> Extended Debugger Ver1.85 94,97/07 by Sey_ju_row CPU [Pentium II] FPU [Present] Machine [PC-98 DOS/V] -r1 <Enter> EAX=000F:0000 EBX=0000:0000 ECX=0000:0000 EDX=4965:0000 ESP=0000:0000 EBP=0000:0000 ESI=0000:0000 EDI=0000:0000 DS=4121 ES=0000 SS=4121 FS=0000 GS=0000 CS=4121 IP=0100 -N11--I--------- 4121:0100 66B800000000 MOV EAX,00000000 -a 4121:0100 mov eax, 0 <Enter> 4121:0106 cpuid <Enter> 4121:0108 int 3 <Enter> 4121:0109 <Enter> -g EAX=0000:0002 EBX=756E:6547 ECX=6C65:746E EDX=4965:6E69 ESP=0000:0000 EBP=0000:0000 ESI=0000:0000 EDI=0000:0000 DS=4121 ES=0000 SS=4121 FS=0000 GS=0000 CS=4121 IP=0108 -N11--I--------- 4121:0108 CC INT 3 -q <Enter> D:\> |
実行できましたか?
eax を 0 に設定して cpuid を実行すると、各register(eax,ebx,ecx,edx)は以下の値を
返してきます。この値で私の cpu が Intel 製の cpu なのが分かります。
蛇足ですが各 register の値は ASCII コードで表わされています。
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
次にバージョン情報を取得してみましょう。
D:\>exdeb <Enter> Extended Debugger Ver1.85 94,97/07 by Sey_ju_row CPU [Pentium II] FPU [Present] Machine [PC-98 DOS/V] -r1 <Enter> EAX=000F:0000 EBX=0000:0000 ECX=0000:0000 EDX=0080:0000 ESP=0000:0000 EBP=0000:0000 ESI=0000:0000 EDI=0000:0000 DS=4121 ES=0000 SS=4121 FS=0000 GS=0000 CS=4121 IP=0100 -N11--I--------- 4121:0100 66B801000000 MOV EAX,00000001 -a <Enter> 4121:0100 mov eax, 1 <Enter> 4121:0106 cpuid <Enter> 4121:0108 int 3 <Enter> 4121:0109 <Enter> -g <Enter> EAX=0000:0634 EBX=0000:0000 ECX=0000:0000 EDX=0080:F9FF ESP=0000:0000 EBP=0000:0000 ESI=0000:0000 EDI=0000:0000 DS=4121 ES=0000 SS=4121 FS=0000 GS=0000 CS=4121 IP=0108 -N11--I--------- 4121:0108 CC INT 3 -q <Enter> D:\> |
今度はどうでしょう。
eax = 1 で cpuid を実行すると以下の値が返ってきます。
通常、バージョン情報で CPU の識別を行ないます。
上記の場合、以下のようになります。
他の CPU については [sandpile.org -- IA-32 architecture -- CPUID] を参照してください。
これ以上説明すると作りかけにならなくなるので止めときます(^^;。
後は「使用した資料」を参照して各々補完してください。
もし CPUID をサポートしていない CPU で CPUID を使用すると、CPU は無効な命令を受け取った事になるわけで、CPU はそれなりの対処をし、os にその後の処理を任せます。Windows ならば一般保護エラー、DOS なら亜空間へ旅経ってしまいます。
実際の所、最近の Intel 製 CPU ではまず CPUID をサポートしていないことはないのですが、Intel互換 CPU ですと、意図的に CPUID をサポートしないように変更できてしまうので注意が必要です。
私が使っている CPUID 判定プログラムを置いておきます。一応、Visual C++ は通るはずです。BC ではチョッチエラーが発生しますがなんとかして (^^;。
BOOL IsCPUID( void ); int main() { if( IsCPUID() ) printf("CPUID is supported!\n"); else printf("CPUID can't be supported...\n"); return 0; } BOOL IsCPUID( void ) { BOOL result = TRUE; _asm{ pushfd pop eax mov ecx, eax xor eax, 0x200000 ; ID ビット push eax popfd pushfd pop eax and eax, 0x200000 ; ID ビットがトルクしない ; ---> can't support CPUID and ecx, 0x200000 ; ID ビットがトルクする ; ---> support CPUID xor eax, ecx jnz jSupCPUID mov result, FALSE jSupCPUID: } return result; } |
他にも参考になる homepage が多数あるのですが、イチイチ紹介していたのでは作りかけにならないので最低限で留めておきます。
|
|
デベロッパ・ホーム(Intel) | Intel 製の CPU ならばここから辿ってください。 |
PentiumII | 一応、私の使っている CPU ということで。 ここの「Pentium(R) IIプロセッサ関連アプリケーション・ノート」のAP-485(AP-485J) に今回説明したCPUID による CPU 判定について述べられています。 さらに「Pentium(R) IIプロセッサ関連マニュアル」に日本語版のマニュアルまであります。 タダってすばらしいっ。 |
sandpile.org | CPUID についてはここが一番詳しいかと思います。 |
#結構時間かかったなぁ。ノベ4時間って所か?
<Home> → <weekly making now!> → <weekly making now! (99.11.13)>
Copyright (c) 1999 Makoto NARA (Mc.N), Some rights reserved.
This web page is licensed under a Creative Commons License.
<Terms of Use>