CPUID命令
x86アーキテクチャではCPUの情報を読み取るにはCPUID命令を使用します。
この命令はeaxレジスタに値をセット後、CPUID命令を実行すると、eax, ebx, edx, ecxレジスタに出力結果がセットされます。
最新のIntelプロセッサでは入力のeaxレジスタには0x00から0x0aまで、拡張命令で0x80000000から0x80000008まで値をとります。
詳しくは "CPUID - CPU Identification" in Chapter 2, "Instruction set Reference, A-M", in the Intel 64 and IA-32 Architectures Software Developer's Manual 2A
例として、eaxレジスタに0をセットし、CPUIDを実行した場合は次の様になる。
#include <stdio.h> #include <stdint.h> #define VENDER_ID_LENGTH 12 struct cpuid_struct { uint32_t basic_info; char vender_id[VENDER_ID_LENGTH]; /* etc */ } cpuid_info; struct registers { uint32_t eax, ebx, edx, ecx; }; void cpuid(uint32_t cmd, struct registers *regs) { asm volatile("cpuid" : "=a" (regs->eax), "=b" (regs->ebx), "=d" (regs->edx), "=c" (regs->ecx) : "a" (cmd)); } int main(void) { int i; struct registers regs; cpuid(0, ®s); cpuid_info.vender_id[0] = regs.eax; cpuid_info.vender_id[0] = regs.ebx; cpuid_info.vender_id[1] = regs.ebx >> 8; cpuid_info.vender_id[2] = regs.ebx >> 16; cpuid_info.vender_id[3] = regs.ebx >> 24; cpuid_info.vender_id[4] = regs.edx; cpuid_info.vender_id[5] = regs.edx >> 8; cpuid_info.vender_id[6] = regs.edx >> 16; cpuid_info.vender_id[7] = regs.edx >> 24; cpuid_info.vender_id[8] = regs.ecx; cpuid_info.vender_id[9] = regs.ecx >> 8; cpuid_info.vender_id[10] = regs.ecx >> 16; cpuid_info.vender_id[11] = regs.ecx >> 24; for (i = 0; i < VENDER_ID_LENGTH; i++) printf("%c", cpuid_info.vender_id[i]); putchar('\n'); return 0; } /* $ gcc cpuid.c && ./a.out * GenuineIntel */