CPUID命令を試す

さて、EFLAGSのIDビットが有効であれば、CPUID命令が使用可能という事で、
実際に、CPUID命令を使ってみます。(代表的な物だけ)

	; CPUID (EAX=0000-0000h)
	XOR	EAX, EAX
;	CPUID
	DB	0x0F, 0xA2

	CALL	puthexl
	MOV	SI, crlf
	CALL	puts

	MOV	[idstr+0], EBX
	MOV	[idstr+4], EDX
	MOV	[idstr+8], ECX
	MOV	SI, idstr
	CALL	puts

CPUIDがコメントアウトされているのは、NASKを[INSTRSET "i386"]で使っているから。
[INSTRSET "i486"]以上であれば、多分、CPUIDは有効になるはず。<まだ試していない
こちらは、基本的な方。
EAXには、有効なファンクションの最大値が返却される。
0000-0004と返ってくれば、0000-0000, 0000-0001, 0000-0002, 0000-0003, 0000-0004 での呼び出しが有効。
将来のCPUで情報を追加し易いような仕様になっているわけですね。


拡張情報取得の方は、以下のようになる。

	; CPUID (EAX=8000-0000h)
	MOV	EAX, 80000000h
;	CPUID
	DB	0x0F, 0xA2

こちらも、同じように、EAXにファンクションの最大値が返却される。


ブランド文字列を取得したい場合は、拡張情報の方を使う。

	; CPUID (EAX=8000-0000h)
	MOV	EAX, 80000000h
;	CPUID
	DB	0x0F, 0xA2

	CMP	EAX, 80000004h
	JB	fin

	; CPUID (EAX=8000-0002h)
	MOV	EAX, 80000002h
;	CPUID
	DB	0x0F, 0xA2

	MOV	[brandstr+00h], EAX
	MOV	[brandstr+04h], EBX
	MOV	[brandstr+08h], ECX
	MOV	[brandstr+0Ch], EDX

	; CPUID (EAX=8000-0003h)
	MOV	EAX, 80000003h
;	CPUID
	DB	0x0F, 0xA2

	MOV	[brandstr+10h], EAX
	MOV	[brandstr+14h], EBX
	MOV	[brandstr+18h], ECX
	MOV	[brandstr+1Ch], EDX

	; CPUID (EAX=8000-0004h)
	MOV	EAX, 80000004h
;	CPUID
	DB	0x0F, 0xA2

	MOV	[brandstr+20h], EAX
	MOV	[brandstr+24h], EBX
	MOV	[brandstr+28h], ECX
	MOV	[brandstr+2Ch], EDX

	MOV	SI, brandstr
	CALL	puts


Qemu上で実行してみたところ、拡張情報の方は失敗するみたい。
実機で試してみたところ、ちゃんと表示された。
Yes!!