CPUID
CPUIDは、x86の機械語命令の一つ(およびそのアセンブリ・ニーモニック)である。CPUの識別 (IDentification) の意。486の後期のステッピングで導入され、Pentiumで完全に公開された[1]。
CPUIDを使用することで、ソフトウェアはプロセッサの形式と機能(例えば、MMXやSSEなどの拡張のサポートの有無)を識別することができる。機械語オペコードは0FA2hであり、オペランドとしてEAXレジスタの値でどのような情報を取得するかを指定する。
CPUID命令が使用可能になるまでは、プロセッサの識別には、それぞれの振舞の微妙な違いを利用する難解なテクニックを駆使する必要があった[2][3](たとえば「PUSH SP」の結果として、PUSHによる変化前と変化後の、どちらの値がプッシュされるか、等)。
CPUID命令の呼び出し編集
CPUID命令は、EAXレジスタが暗黙のオペランドであり、それ以外の(明示的な)オペランドは無い。どのような情報を返すべきかを指定する値をEAXレジスタに設定し、CPUID命令を実行する。まずEAX = 0
でCPUIDを呼び出し、CPUでサポートされている最大のパラメータを取得するべきである。CPUIDの拡張機能情報を取得する場合は、EAXのビット31をセットしてCPUIDを呼び出す。拡張機能情報でサポートされている最大の機能番号を得るためには、EAX = 8000000h
でCPUIDを呼び出す。
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\n"
s1: .string "Vendor ID: %s\n"
.text
.global main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
subl %eax, %eax
cpuid
subq $8, %rsp
movl %ebx, (%rsp)
movl %edx, 4(%rsp)
movl %ecx, 8(%rsp)
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
EAX=1: プロセッサ情報とプロセッサの機能編集
これはCPUのステッピング、モデル、ファミリーをEAXに返す(これはCPUの「シグネチャ」とも呼ばれる)。また、機能フラグをEDXとECXに、追加の機能情報をEBXに返す。
EAXに格納される情報のフォーマットは以下のとおり:
- 3:0 - ステッピング
- 7:4 - モデル
- 11:8 - ファミリー
- 13:12 - プロセッサタイプ
- 19:16 - 拡張モデル
- 27:20 - 拡張ファミリー
インテルとAMDは、CPUのファミリーを上記の「ファミリー」と「拡張ファミリー」の合計で表示し、モデルを上記の「モデル」と4ビット左シフトした「拡張モデル」の合計で表示するように提案した。
プロセッサ情報と機能フラグはメーカ個別のものであるが、通常は互換性のためにインテルの値を他のメーカも使用している。
EAX=2: キャッシュとTLBディスクリプタ情報編集
これは、キャッシュとTLBの機能を示すディスクリプタのリストをEAX, EBX, ECX, EDXレジスタに格納する。
EAX=3: プロセッサ・シリアル・ナンバ編集
これは、プロセッサのシリアル番号を返す。プロセッサ・シリアル・ナンバは、インテルがPentium IIIで導入したが、プライバシーの懸念のためにこの後のモデルでは実装されていない(PSN機能ビットは常にクリアされている)。トランスメタの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\n"
.text
.global main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
movl $1, %eax
cpuid
subq $4, %rsp
movl %eax, (%rsp)
movq 2(%rsp), %rbx
movw %bx, (%rsp)
movw %ax, 2(%rsp)
movl $3, %eax
cpuid
movl %edx, 4(%rsp)
movq 6(%rsp), %rax
movw %ax, 4(%rsp)
movw %dx, 6(%rsp)
movl %ecx, 8(%rsp)
movl $s0, %edi
movw (%rsp), %si
movw 2(%rsp), %dx
movw 4(%rsp), %cx
movw 6(%rsp), %r8w
movw 8(%rsp), %r8w
movw 10(%rsp), %r9w
movw %r9w, (%rsp)
subl %eax, %eax
call printf
subl %eax, %eax
movq %rbp, %rsp
popq %rbp
ret
EAX=80000000h: サポートする最大拡張機能番号の取得編集
最大の拡張機能番号をEAXに格納する。
EAX=80000001h: 拡張プロセッサ情報とプロセッサの機能編集
拡張機能フラグをEDXとECXに格納する。
EAX=80000002h,80000003h,80000004h: プロセッサブランド文字列編集
プロセッサブランド文字列をEAX, EBX, ECX, EDXに格納する。全体で48バイトのNULL終端ASCII文字列のプロセッサブランド文字列を得るために、各パラメータを順番に設定しCPUIDを呼び出す必要がある。
.section .data
s0: .string "Processor Brand String: %s\n"
.text
.global main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
subq $44, %rsp
movl $0x80000002, %eax
cpuid
movl %eax, (%rsp)
movl %ebx, 4(%rsp)
movl %ecx, 8(%rsp)
movl %edx, 12(%rsp)
addq $16, %rsp
movl $0x80000003, %eax
cpuid
movl %eax, (%rsp)
movl %ebx, 4(%rsp)
movl %ecx, 8(%rsp)
movl %edx, 12(%rsp)
addq $16, %rsp
movl $0x80000004, %eax
cpuid
movl %eax, (%rsp)
movl %ebx, 4(%rsp)
movl %ecx, 8(%rsp)
movl %edx, 12(%rsp)
subq $32, %rsp
movl $s0, %edi
movq %rsp, %rsi
subl %eax, %eax
call printf
subl %eax, %eax
movq %rbp, %rsp
popq %rbp
ret
EAX=80000005h: 予約編集
この機能は使用されていない。
EAX=80000006h: 拡張L2キャッシュ情報編集
ECXにL2キャッシュの詳細情報を格納する。2種類の方法で表したキャッシュサイズと、キャッシュとメモリの対応を示すコードを含む。
.section .data
s0: .string "L2 Cache: %iMB\n"
.text
.global main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
movl $0x80000006, %eax
cpuid
subl %edx, %edx
movl %ecx, (%rsp)
movl 2(%rsp), %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
EAX=80000007h: 予約編集
この機能は使用されていない。
EAX=80000008h: 仮想アドレスと物理アドレスのサイズ編集
最大の仮想アドレスサイズと物理アドレスサイズをEAXに格納する。
関連項目編集
- Pentium III: プライバシーに関する論争
- CPU-Z: 各種のシステム情報を取得するためにCPUIDを使用するWindowsユーティリティ
外部リンク編集
- http://www.sandpile.org/ia32/cpuid.htm
- http://www.sandpile.org/ -- x86プロセッサの技術的な情報
- CPUID ガイド:
- Windows プログラム:
- DOS プログラム:
- Linux プログラム:
- http://www.etallen.com/cpuid.html
- http://www.ka9q.net/code/cpuid/
- /proc/cpuinfoインタフェースは、他の情報とあわせて、CPUIDからの出力を多く表示する
- Solarisは/dev/cpu/self/cpuidインタフェースを提供している