首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 內嵌組語 CPUID 指令取得 CPU 廠商、型號、MMX/SSE 支援資訊

     編輯:VC 教學

CPUID 指令基礎

機器碼 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;
}

注意事項

  • MSVC 內嵌組語需將輸出存入記憶體變數 (如上巨集),不能直接對寄存器變數賦值。
  • 編譯器優化可能重排指令,關鍵區段建議 #pragma optimize("", off) 或加 volatile。
  • 64 位元編譯不支援內嵌組語,需改用 __cpuid 內建函數 (intrin.h) 或單獨 .asm 模組。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved