機器碼 0F A2。輸入 EAX 功能碼,輸出 EAX, EBX, ECX, EDX。支援:Intel 486+、Cyrix M1+、AMD Am486+。
| EAX 輸入 | 用途 | 關鍵輸出暫存器 |
|---|---|---|
| 0 | 最高功能碼 + 廠商字串 | EAX=MaxFunc, EBX/EDX/ECX = "GenuineIntel" / "AuthenticAMD" / "CyrixInstead" |
| 1 | 處理器簽名與特徵旗標 | EAX[11:8]=Family (4=486, 5=Pentium, 6=P6), EDX[0]=FPU, EDX[23]=MMX, EDX[25]=SSE, EDX[26]=SSE2 |
| 2 | 快取描述符 | EAX/EBX/ECX/EDX 為描述符陣列 |
| 80000000h | 擴展功能碼上限 | EAX = MaxExtFunc |
| 80000001h | 擴展特徵旗標 (AMD) | EDX[31]=3DNow!, EDX[30]=3DNow!+, EDX[29]=MMX+ |
| 80000002h~04h | 處理器品牌字串 (ASCII) | EAX/EBX/ECX/EDX 連續 48 字元 |
#include
#include
using namespace std;
void CpuId(int func, int& eax, int& ebx, int& ecx, int& edx) {
__asm {
mov eax, func
cpuid
mov esi, eax; mov [eax], esi // 這裡為示意,實際需存入參考參數
// 正確寫法見下方
}
}
// 正確內嵌組語 (MSVC)
#define CPUID(func, eax, ebx, ecx, edx) \
__asm { \
mov eax, func; \
cpuid; \
mov dword ptr [eax], eax; \
mov dword ptr [ebx], ebx; \
mov dword ptr [ecx], ecx; \
mov dword ptr [edx], edx; \
}
int main() {
int eax, ebx, ecx, edx;
char vendor[13] = {0};
// 1. 廠商字串
CPUID(0, eax, ebx, ecx, edx);
*(int*)vendor = ebx; *(int*)(vendor+4) = edx; *(int*)(vendor+8) = ecx;
cout << "Vendor: " << vendor << endl; // "GenuineIntel" / "AuthenticAMD" ...
// 2. 型號與特徵
CPUID(1, eax, ebx, ecx, edx);
int family = (eax >> 8) & 0xF;
int model = (eax >> 4) & 0xF;
int stepping = eax & 0xF;
cout << "Family: " << family << " Model: " << model << " Stepping: " << stepping << endl;
bool hasMMX = (edx >> 23) & 1;
bool hasSSE = (edx >> 25) & 1;
bool hasSSE2 = (edx >> 26) & 1;
cout << "MMX: " << hasMMX << " SSE: " << hasSSE << " SSE2: " << hasSSE2 << endl;
// 3. AMD 擴展品牌字串
CPUID(0x80000000, eax, ebx, ecx, edx);
if (eax >= 0x80000004) {
char brand[49] = {0};
CPUID(0x80000002, eax, ebx, ecx, edx);
*(int*)brand = eax; *(int*)(brand+4) = ebx; *(int*)(brand+8) = ecx; *(int*)(brand+12) = edx;
CPUID(0x80000003, eax, ebx, ecx, edx);
*(int*)(brand+16) = eax; *(int*)(brand+20) = ebx; *(int*)(brand+24) = ecx; *(int*)(brand+28) = edx;
CPUID(0x80000004, eax, ebx, ecx, edx);
*(int*)(brand+32) = eax; *(int*)(brand+36) = ebx; *(int*)(brand+40) = ecx; *(int*)(brand+44) = edx;
cout << "Brand: " << brand << endl;
}
return 0;
}
#pragma optimize("", off) 或加 volatile。__cpuid 內建函數 (intrin.h) 或單獨 .asm 模組。