AMD64アセンブラ/AMD64 CPU情報表示ツール
表示
AMD64/x86_64アーキテクチャ向けのCPUID情報表示ツールを作成しました。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <cpuid.h> // CPUID命令を実行する関数 static inline void cpuid(unsigned int leaf, unsigned int subleaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { __cpuid_count(leaf, subleaf, *eax, *ebx, *ecx, *edx); } // ベンダー文字列の取得 void get_vendor_string(char *vendor) { unsigned int eax, ebx, ecx, edx; cpuid(0, 0, &eax, &ebx, &ecx, &edx); memcpy(vendor, &ebx, 4); memcpy(vendor + 4, &edx, 4); memcpy(vendor + 8, &ecx, 4); vendor[12] = '\0'; } // プロセッサブランド文字列の取得 void get_brand_string(char *brand) { unsigned int eax, ebx, ecx, edx; for (int i = 0; i < 3; i++) { cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx); memcpy(brand + (i * 16), &eax, 4); memcpy(brand + (i * 16) + 4, &ebx, 4); memcpy(brand + (i * 16) + 8, &ecx, 4); memcpy(brand + (i * 16) + 12, &edx, 4); } brand[48] = '\0'; } // 基本CPU情報のデコード void decode_cpu_signature() { unsigned int eax, ebx, ecx, edx; cpuid(1, 0, &eax, &ebx, &ecx, &edx); unsigned int stepping = eax & 0xF; unsigned int model = (eax >> 4) & 0xF; unsigned int family = (eax >> 8) & 0xF; unsigned int processor_type = (eax >> 12) & 0x3; unsigned int extended_model = (eax >> 16) & 0xF; unsigned int extended_family = (eax >> 20) & 0xFF; // 実際のファミリーとモデルの計算 unsigned int display_family = family; unsigned int display_model = model; if (family == 0xF) { display_family = family + extended_family; } if (family == 0x6 || family == 0xF) { display_model = (extended_model << 4) + model; } printf("=== CPU Signature (CPUID.01H:EAX) ===\n"); printf("Raw value: 0x%08x\n", eax); printf("Stepping: %u\n", stepping); printf("Model: 0x%x (%u)\n", display_model, display_model); printf("Family: 0x%x (%u)\n", display_family, display_family); printf("Processor Type: %u ", processor_type); switch(processor_type) { case 0: printf("(Original OEM Processor)\n"); break; case 1: printf("(Intel OverDrive Processor)\n"); break; case 2: printf("(Dual Processor)\n"); break; case 3: printf("(Reserved)\n"); break; } printf("Brand Index: %u\n", ebx & 0xFF); printf("CLFLUSH line size: %u bytes\n", ((ebx >> 8) & 0xFF) * 8); printf("Max Addressable IDs: %u\n", (ebx >> 16) & 0xFF); printf("Initial APIC ID: %u\n", (ebx >> 24) & 0xFF); printf("\n"); } // キャッシュ情報の取得と表示 void decode_cache_info() { unsigned int eax, ebx, ecx, edx; printf("=== Cache and TLB Information ===\n"); // Intel方式: CPUID.04H cpuid(0, 0, &eax, &ebx, &ecx, &edx); if (eax >= 4) { int cache_level = 0; while (1) { cpuid(4, cache_level, &eax, &ebx, &ecx, &edx); unsigned int cache_type = eax & 0x1F; if (cache_type == 0) break; unsigned int level = (eax >> 5) & 0x7; unsigned int ways = ((ebx >> 22) & 0x3FF) + 1; unsigned int partitions = ((ebx >> 12) & 0x3FF) + 1; unsigned int line_size = (ebx & 0xFFF) + 1; unsigned int sets = ecx + 1; unsigned int size = ways * partitions * line_size * sets; printf("L%u ", level); switch(cache_type) { case 1: printf("Data Cache: "); break; case 2: printf("Instruction Cache: "); break; case 3: printf("Unified Cache: "); break; } printf("%u KB, %u-way, %u byte line size\n", size / 1024, ways, line_size); cache_level++; } } // AMD方式: CPUID.8000001DH cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx); if (eax >= 0x80000006) { cpuid(0x80000006, 0, &eax, &ebx, &ecx, &edx); unsigned int l2_line = ecx & 0xFF; unsigned int l2_assoc = (ecx >> 12) & 0xF; unsigned int l2_size = (ecx >> 16) & 0xFFFF; printf("L2 Cache: %u KB, line size %u bytes\n", l2_size, l2_line); unsigned int l3_line = edx & 0xFF; unsigned int l3_assoc = (edx >> 12) & 0xF; unsigned int l3_size = ((edx >> 18) & 0x3FFF) * 512; if (l3_size > 0) { printf("L3 Cache: %u KB, line size %u bytes\n", l3_size / 1024, l3_line); } } printf("\n"); } // 機能フラグの確認 void check_feature_flags() { unsigned int eax, ebx, ecx, edx; printf("=== Feature Flags (CPUID.01H) ===\n"); cpuid(1, 0, &eax, &ebx, &ecx, &edx); printf("ECX Features:\n"); if (ecx & (1 << 0)) printf(" - SSE3\n"); if (ecx & (1 << 1)) printf(" - PCLMULQDQ\n"); if (ecx & (1 << 3)) printf(" - MONITOR/MWAIT\n"); if (ecx & (1 << 5)) printf(" - VMX (Virtual Machine Extensions)\n"); if (ecx & (1 << 6)) printf(" - SMX (Safer Mode Extensions)\n"); if (ecx & (1 << 9)) printf(" - SSSE3\n"); if (ecx & (1 << 12)) printf(" - FMA\n"); if (ecx & (1 << 13)) printf(" - CMPXCHG16B\n"); if (ecx & (1 << 19)) printf(" - SSE4.1\n"); if (ecx & (1 << 20)) printf(" - SSE4.2\n"); if (ecx & (1 << 22)) printf(" - MOVBE\n"); if (ecx & (1 << 23)) printf(" - POPCNT\n"); if (ecx & (1 << 25)) printf(" - AES\n"); if (ecx & (1 << 26)) printf(" - XSAVE\n"); if (ecx & (1 << 28)) printf(" - AVX\n"); if (ecx & (1 << 29)) printf(" - F16C\n"); if (ecx & (1 << 30)) printf(" - RDRAND\n"); printf("\nEDX Features:\n"); if (edx & (1 << 0)) printf(" - FPU (x87 FPU)\n"); if (edx & (1 << 4)) printf(" - TSC (Time Stamp Counter)\n"); if (edx & (1 << 5)) printf(" - MSR (Model Specific Registers)\n"); if (edx & (1 << 6)) printf(" - PAE (Physical Address Extension)\n"); if (edx & (1 << 8)) printf(" - CX8 (CMPXCHG8B)\n"); if (edx & (1 << 9)) printf(" - APIC\n"); if (edx & (1 << 11)) printf(" - SEP (SYSENTER/SYSEXIT)\n"); if (edx & (1 << 13)) printf(" - PGE (Page Global Enable)\n"); if (edx & (1 << 15)) printf(" - CMOV\n"); if (edx & (1 << 19)) printf(" - CLFSH (CLFLUSH)\n"); if (edx & (1 << 23)) printf(" - MMX\n"); if (edx & (1 << 24)) printf(" - FXSR (FXSAVE/FXRSTOR)\n"); if (edx & (1 << 25)) printf(" - SSE\n"); if (edx & (1 << 26)) printf(" - SSE2\n"); if (edx & (1 << 28)) printf(" - HTT (Hyper-Threading)\n"); // 拡張機能フラグ cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx); if (eax >= 0x80000001) { cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx); printf("\nExtended ECX Features:\n"); if (ecx & (1 << 0)) printf(" - LAHF/SAHF in 64-bit mode\n"); if (ecx & (1 << 5)) printf(" - ABM (Advanced Bit Manipulation)\n"); if (ecx & (1 << 6)) printf(" - SSE4A\n"); if (ecx & (1 << 8)) printf(" - PREFETCHW\n"); if (ecx & (1 << 11)) printf(" - XOP\n"); if (ecx & (1 << 16)) printf(" - FMA4\n"); if (ecx & (1 << 21)) printf(" - TBM (Trailing Bit Manipulation)\n"); printf("\nExtended EDX Features:\n"); if (edx & (1 << 11)) printf(" - SYSCALL/SYSRET\n"); if (edx & (1 << 20)) printf(" - NX (Execute Disable Bit)\n"); if (edx & (1 << 22)) printf(" - MMXEXT\n"); if (edx & (1 << 26)) printf(" - 1GB Pages\n"); if (edx & (1 << 27)) printf(" - RDTSCP\n"); if (edx & (1 << 29)) printf(" - Long Mode (64-bit)\n"); if (edx & (1 << 30)) printf(" - 3DNow!+\n"); if (edx & (1 << 31)) printf(" - 3DNow!\n"); } // AVX2などの追加機能 cpuid(0, 0, &eax, &ebx, &ecx, &edx); if (eax >= 7) { cpuid(7, 0, &eax, &ebx, &ecx, &edx); printf("\nStructured Extended Features (Leaf 7):\n"); if (ebx & (1 << 3)) printf(" - BMI1\n"); if (ebx & (1 << 5)) printf(" - AVX2\n"); if (ebx & (1 << 8)) printf(" - BMI2\n"); if (ebx & (1 << 16)) printf(" - AVX512F\n"); if (ebx & (1 << 18)) printf(" - RDSEED\n"); if (ebx & (1 << 19)) printf(" - ADX\n"); if (ebx & (1 << 29)) printf(" - SHA\n"); } printf("\n"); } // /proc/cpuinfoから情報を読み取る void read_proc_cpuinfo() { FILE *fp = fopen("/proc/cpuinfo", "r"); if (!fp) { perror("Failed to open /proc/cpuinfo"); return; } printf("=== /proc/cpuinfo Information ===\n"); char line[256]; int cpu_count = 0; while (fgets(line, sizeof(line), fp)) { if (strncmp(line, "processor", 9) == 0) { cpu_count++; } else if (strncmp(line, "model name", 10) == 0 || strncmp(line, "cpu family", 10) == 0 || strncmp(line, "model", 5) == 0 || strncmp(line, "stepping", 8) == 0 || strncmp(line, "cpu MHz", 7) == 0 || strncmp(line, "cache size", 10) == 0 || strncmp(line, "physical id", 11) == 0 || strncmp(line, "siblings", 8) == 0 || strncmp(line, "core id", 7) == 0 || strncmp(line, "cpu cores", 9) == 0) { if (cpu_count <= 1) { // 最初のCPUの情報のみ表示 printf("%s", line); } } } printf("Total logical processors: %d\n\n", cpu_count); fclose(fp); } // トポロジー情報の取得 void decode_topology() { unsigned int eax, ebx, ecx, edx; printf("=== CPU Topology ===\n"); cpuid(1, 0, &eax, &ebx, &ecx, &edx); unsigned int max_logical = (ebx >> 16) & 0xFF; printf("Maximum addressable logical processors: %u\n", max_logical); cpuid(0, 0, &eax, &ebx, &ecx, &edx); if (eax >= 0xB) { int level = 0; while (1) { cpuid(0xB, level, &eax, &ebx, &ecx, &edx); unsigned int level_type = (ecx >> 8) & 0xFF; if (level_type == 0) break; unsigned int shift = eax & 0x1F; unsigned int num_logical = ebx & 0xFFFF; printf("Level %d: ", level); switch(level_type) { case 1: printf("SMT (threads per core)"); break; case 2: printf("Core"); break; default: printf("Unknown"); break; } printf(" - %u logical processors, shift %u\n", num_logical, shift); level++; } } printf("\n"); } int main() { printf("AMD64/x86_64 CPU Information Display\n"); printf("=====================================\n\n"); // ベンダー文字列の取得 char vendor[13]; get_vendor_string(vendor); printf("=== Vendor Information ===\n"); printf("Vendor ID: %s\n", vendor); // 対応している最大CPUIDリーフの確認 unsigned int max_leaf, ebx, ecx, edx; cpuid(0, 0, &max_leaf, &ebx, &ecx, &edx); printf("Maximum standard CPUID leaf: 0x%x\n", max_leaf); cpuid(0x80000000, 0, &max_leaf, &ebx, &ecx, &edx); printf("Maximum extended CPUID leaf: 0x%x\n", max_leaf); // ブランド文字列の取得 if (max_leaf >= 0x80000004) { char brand[49]; get_brand_string(brand); printf("Processor Brand: %s\n", brand); } printf("\n"); // CPU署名のデコード decode_cpu_signature(); // キャッシュ情報の表示 decode_cache_info(); // トポロジー情報 decode_topology(); // 機能フラグの確認 check_feature_flags(); // /proc/cpuinfoから情報を読み取り read_proc_cpuinfo(); // 基本的なシステム情報 printf("=== System Information ===\n"); printf("Page size: %ld bytes\n", sysconf(_SC_PAGESIZE)); printf("Number of processors online: %ld\n", sysconf(_SC_NPROCESSORS_ONLN)); printf("Number of processors configured: %ld\n", sysconf(_SC_NPROCESSORS_CONF)); return 0; }
- 実行例
AMD64/x86_64 CPU Information Display ===================================== === Vendor Information === Vendor ID: GenuineIntel Maximum standard CPUID leaf: 0x1f Maximum extended CPUID leaf: 0x80000008 Processor Brand: Intel(R) N100 === CPU Signature (CPUID.01H:EAX) === Raw value: 0x000b06e0 Stepping: 0 Model: 0xbe (190) Family: 0x6 (6) Processor Type: 0 (Original OEM Processor) Brand Index: 0 CLFLUSH line size: 64 bytes Max Addressable IDs: 4 Initial APIC ID: 2 === Cache and TLB Information === L1 Data Cache: 32 KB, 8-way, 64 byte line size L1 Instruction Cache: 64 KB, 8-way, 64 byte line size L2 Unified Cache: 2048 KB, 16-way, 64 byte line size L3 Unified Cache: 6144 KB, 12-way, 64 byte line size L2 Cache: 2048 KB, line size 64 bytes === CPU Topology === Maximum addressable logical processors: 4 Level 0: SMT (threads per core) - 1 logical processors, shift 0 === Feature Flags (CPUID.01H) === ECX Features: - SSE3 - PCLMULQDQ - VMX (Virtual Machine Extensions) - SSSE3 - FMA - CMPXCHG16B - SSE4.1 - SSE4.2 - MOVBE - POPCNT - AES - XSAVE - AVX - F16C - RDRAND EDX Features: - FPU (x87 FPU) - TSC (Time Stamp Counter) - MSR (Model Specific Registers) - PAE (Physical Address Extension) - CX8 (CMPXCHG8B) - APIC - SEP (SYSENTER/SYSEXIT) - PGE (Page Global Enable) - CMOV - CLFSH (CLFLUSH) - MMX - FXSR (FXSAVE/FXRSTOR) - SSE - SSE2 - HTT (Hyper-Threading) Extended ECX Features: - LAHF/SAHF in 64-bit mode - ABM (Advanced Bit Manipulation) - PREFETCHW Extended EDX Features: - SYSCALL/SYSRET - NX (Execute Disable Bit) - 1GB Pages - RDTSCP - Long Mode (64-bit) Structured Extended Features (Leaf 7): - BMI1 - AVX2 - BMI2 - RDSEED - ADX - SHA === /proc/cpuinfo Information === cpu family : 6 model : 190 model name : Intel(R) N100 stepping : 0 cpu MHz : 806.400 cache size : 6144 KB physical id : 0 siblings : 1 core id : 0 cpu cores : 1 Total logical processors: 4 === System Information === Page size: 4096 bytes Number of processors online: 4 Number of processors configured: 4
AMD64/x86_64版のCPU情報表示ツールを作成しました。主な特徴は以下の通りです:
主な機能
[編集]- CPUID命令によるCPU情報取得
- ベンダーID(Intel、AMD等)
- プロセッサブランド文字列
- ファミリー、モデル、ステッピング情報
- キャッシュ階層の詳細情報
- L1/L2/L3キャッシュのサイズと構成
- キャッシュラインサイズ
- ウェイ数
- 豊富な機能フラグ検出
- SSE/SSE2/SSE3/SSSE3/SSE4.1/SSE4.2
- AVX/AVX2/AVX512
- AES-NI、SHA拡張命令
- 仮想化支援機能(VMX)
- 64ビットモード対応確認
- CPUトポロジー情報
- 論理プロセッサ数
- SMT/ハイパースレッディング情報
- コア数の取得
- /proc/cpuinfoとの連携
- カーネルから見たCPU情報との照合
コンパイルと実行
[編集]clang -o cpuinfo_amd64 cpuinfo_amd64.c ./cpuinfo_amd64
ARM64版と同様に、システムの深い部分から直接ハードウェア情報を取得し、詳細な分析を提供します。