CPUID

CPUIDは、x86の機械語命令の一つである。CPUの識別  の意。486の後期のステッピングで導入され、Pentiumで完全に公開された[1]。

CPUIDを使用することで、ソフトウェアはプロセッサの形式と機能を識別することができる。機械語オペコードは0FA2hであり、オペランドとしてEAXレジスタの値でどのような情報を取得するかを指定する。

1. CPUID命令の使用可否
---------------

CPUID命令は一部の80486およびそれ以降のプロセッサで利用できるため、場合によってはCPUID命令が存在するプロセッサであるか否かを事前に判別する必要が生じる。80486以前のプロセッサを識別する必要がある場合には、それぞれの振舞の微妙な違いを利用する難解なテクニックを駆使する必要があった[2][3]。

80486以上のプロセッサであることが確認できた場合、CPUID命令の存在を確認するためのフラグとして32ビットフラグレジスタ  の第21ビットが新たに設けられているため、このビットが「変更可能」であればCPUID命令が使用可能であると判断できる。なおEFLAGSは80386以上のプロセッサであればアクセスできるため、80286以下のプロセッサを判別・除外しておく必要はあるものの、CPUID命令の有無だけを調べたいのであれば実質的に80386以上であることが確認できればこのフラグを調べることができる。

2. CPUID命令の呼び出し
---------------

CPUID命令は、EAXレジスタが暗黙のオペランドであり、それ以外のオペランドは無い。どのような情報を返すべきかを指定する値をEAXレジスタに設定し、CPUID命令を実行する。まずEAX = 0でCPUIDを呼び出し、CPUでサポートされている最大のパラメータを取得するべきである。CPUIDの拡張機能情報を取得する場合は、EAXのビット31をセットしてCPUIDを呼び出す。拡張機能情報でサポートされている最大の機能番号を得るためには、EAX = 8000000hでCPUIDを呼び出す。

2.1. EAX=0: ベンダIDの取得
--------------------

これは、CPUベンダのID文字列を返す。12文字のASCII文字列がEBX, EDX, ECXの順序で格納される。基本機能の最大機能番号がEAXに格納される。

既知のCPUベンダのID文字列は以下のとおり：

"AMDisbetter!" - AMD K5の初期のエンジニアリングサンプル
"AuthenticAMD" - AMD
"CentaurHauls" - セントールテクノロジー
"CyrixInstead" - サイリックス
"GenuineIntel" - インテル
"GenuineTMx86", "TransmetaCPU" - トランスメタ
"Geode by NSC" - ナショナル セミコンダクター
"NexGenDriven" - NexGen
"RiseRiseRise" - Rise Technology
"SiS SiS SiS " - SiS
"UMC UMC UMC " - UMC
"VIA VIA VIA " - VIA Technologies例えば、ベンダIDが"GenuineIntel"の場合、EBXが0x756e6547、EDXが0x49656e69、ECXが0x6c65746eとなる。 .section .data s0: .string "Largest Standard Function Number Supported: %i " s1: .string "Vendor ID: %s " .text .global main

.type main, @function main: pushq %rbp movq %rsp, %rbp

subl %eax, %eax cpuid

subq $8, %rsp movl %ebx,  movl %edx, 4 movl %ecx, 8 movl $s0, %edi movl %eax, %esi subl %eax, %eax call printf

movq $s1, %rdi movq %rsp, %rsi subl %eax, %eax call printf

subl %eax, %eax movq %rbp, %rsp popq %rbp ret<WtXmlEndTag />

2.2. EAX=1: プロセッサ情報とプロセッサの機能
----------------------------

これはCPUのステッピング、モデル、ファミリーをEAXに返す。また、機能フラグをEDXとECXに、追加の機能情報をEBXに返す。

EAXに格納される情報のフォーマットは以下のとおり:

3:0 - ステッピング
7:4 - モデル
11:8 - ファミリー
13:12 - プロセッサタイプ
19:16 - 拡張モデル
27:20 - 拡張ファミリーインテルとAMDは、CPUのファミリーを上記の「ファミリー」と「拡張ファミリー」の合計で表示し、モデルを上記の「モデル」と4ビット左シフトした「拡張モデル」の合計で表示するように提案した。

プロセッサ情報と機能フラグはメーカ個別のものであるが、通常は互換性のためにインテルの値を他のメーカも使用している。

また、80386以上のプロセッサではリセット直後のDXレジスタにはこれらの情報に相当する値が格納されているため、ハード構成によっては80286がプロテクトモードからリアルモードに戻るためのリセット機構を利用することで、386/486系プロセッサでもファミリ・モデル・ステッピングなどに相当する情報を得られる場合がある。詳細はIntel 80286およびIntel 80386を参照。



2.3. EAX=2: キャッシュとTLBディスクリプタ情報
------------------------------

これは、キャッシュとTLBの機能を示すディスクリプタのリストをEAX, EBX, ECX, EDXレジスタに格納する。

2.4. EAX=3: プロセッサ・シリアル・ナンバ
--------------------------

これは、プロセッサのシリアル番号を返す。プロセッサ・シリアル・ナンバは、インテルがPentium IIIで導入したが、プライバシーの懸念のためにこの後のモデルでは実装されていない。トランスメタのEfficeonとCrusoeプロセッサはこの機能を提供している。AMDは、この機能をどのCPUにも実装しなかった。

インテルPentium IIIでは、シリアル番号はEDX:ECXレジスタに格納される。トランスメタのEfficeonではEBX:EAXレジスタに、CrusoeではEBXレジスタだけに格納される。

プロセッサ・シリアル・ナンバ機能を使用するためには、BIOSの設定を有効にする必要があることに注意すべきである。 .section .data s0: .string "Processor serial number: %.4hX-%.4hX-%.4hX-%.4hX-%.4hX-%.4hX " .text .global main

.type main, @function main: pushq %rbp movq %rsp, %rbp

movl $1, %eax cpuid

subq $4, %rsp movl %eax,  movq 2, %rbx movw %bx,  movw %ax, 2

movl $3, %eax cpuid

movl %edx, 4 movq 6, %rax movw %ax, 4 movw %dx, 6 movl %ecx, 8

movl $s0, %edi movw , %si movw 2, %dx movw 4, %cx movw 6, %r8w movw 8, %r8w movw 10, %r9w movw %r9w,  subl %eax, %eax call printf

subl %eax, %eax movq %rbp, %rsp popq %rbp ret<WtXmlEndTag />

2.5. EAX=80000000h: サポートする最大拡張機能番号の取得
-------------------------------------

最大の拡張機能番号をEAXに格納する。

2.6. EAX=80000001h: 拡張プロセッサ情報とプロセッサの機能
--------------------------------------

AMD社のCPUの拡張機能フラグをEDXとECXに格納する。 EDXのビット 0 から 9, 12 から 17, 23と 24は、AMDのCPUではEAX=1の場合のCPUIDの結果と重複し、IntelのCPUでは未使用である。IntelのCPUでもsyscall, nx, pdpe1gb, rdtscp, lm, lahf_lm, abm/lzcnt, 3dnowprefetchに対応しているものもある。



2.7. EAX=80000002h,80000003h,80000004h: プロセッサブランド文字列
----------------------------------------------------

プロセッサブランド文字列をEAX, EBX, ECX, EDXに格納する。全体で48バイトのNULL終端ASCII文字列のプロセッサブランド文字列を得るために、各パラメータを順番に設定しCPUIDを呼び出す必要がある。 .section .data s0: .string "Processor Brand String: %s " .text .global main

.type main, @function main: pushq %rbp movq %rsp, %rbp

subq $44, %rsp movl $0x80000002, %eax cpuid

movl %eax,  movl %ebx, 4 movl %ecx, 8 movl %edx, 12 addq $16, %rsp

movl $0x80000003, %eax cpuid

movl %eax,  movl %ebx, 4 movl %ecx, 8 movl %edx, 12 addq $16, %rsp

movl $0x80000004, %eax cpuid

movl %eax,  movl %ebx, 4 movl %ecx, 8 movl %edx, 12 subq $32, %rsp

movl $s0, %edi movq %rsp, %rsi subl %eax, %eax call printf

subl %eax, %eax movq %rbp, %rsp popq %rbp ret<WtXmlEndTag />

2.8. EAX=80000005h: 予約
----------------------

この機能は使用されていない。

2.9. EAX=80000006h: 拡張L2キャッシュ情報
-------------------------------

ECXにL2キャッシュの詳細情報を格納する。2種類の方法で表したキャッシュサイズと、キャッシュとメモリの対応を示すコードを含む。 .section .data s0: .string "L2 Cache: %iMB " .text .global main

.type main, @function main: pushq %rbp movq %rsp, %rbp

movl $0x80000006, %eax cpuid

subl %edx, %edx movl %ecx,  movl 2, %eax movl $1024, %ecx divl %ecx

movl $s0, %edi movl %eax, %esi subl %eax, %eax call printf

subl %eax, %eax movq %rbp, %rsp popq %rbp ret<WtXmlEndTag />

2.10. EAX=80000007h: 予約
-----------------------

この機能は使用されていない。

2.11. EAX=80000008h: 仮想アドレスと物理アドレスのサイズ
--------------------------------------

最大の仮想アドレスサイズと物理アドレスサイズをEAXに格納する。

3. 関連項目
-------

Pentium III: プライバシーに関する論争
CPU-Z: 各種のシステム情報を取得するためにCPUIDを使用するWindowsユーティリティ

4. 脚注
-----

5. 注釈
-----

6. 外部リンク
--------

http://www.sandpile.org/ia32/cpuid.htm
http://www.sandpile.org/ -- x86プロセッサの技術的な情報
CPUID ガイド:
[4] 
[5] 
Windows プログラム:
SIV http://rh-software.com/
CPUZ http://www.cpuid.com/
WCPUID http://hp.vector.co.jp/authors/VA002374/src/download.html
DOS プログラム:
http://www.coli.uni-saarland.de/~eric/stuff/soft/specials/cpulevel2007.zip
http://glstation.free.fr/mine/djgpp/download/cpu.zip
http://www.volny.cz/rayer/programm/programe.htm 
Linux プログラム:
http://www.etallen.com/cpuid.html
http://www.ka9q.net/code/cpuid/
///proc/cpuinfo//インタフェースは、他の情報とあわせて、CPUIDからの出力を多く表示する
Solarisは///dev/cpu/self/cpuid//インタフェースを提供している
http://blogs.sun.com/JoeBonasera/entry/detecting_hardware_virtualization_support_for