擷取CPU資訊
主要是利用彙編指令 CPUID 和 RDTSC
直接上代碼:
//=====================================================================================/* CPUID指令是intel IA32架構下獲得CPU資訊的彙編指令, 可以得到CPU類型,型號,製造商資訊,商標資訊,序號, 緩衝等一系列CPU相關的東西。*/#include <windows.h>#include <iostream>#include <string>using namespace std;//用來儲存eax,ebx,ecx,edx四個寄存器的資訊DWORD deax;DWORD debx;DWORD decx;DWORD dedx;void ExeCPUID(DWORD veax) //初始化CPU{__asm{ mov eax,veax cpuid mov deax,eax mov debx,ebx mov decx,ecx mov dedx,edx}}/*在Intel Pentium以上層級的CPU中,有一個稱為“時間戳記(Time Stamp)”的組件,它以64位無符號整型數的格式,記錄了自CPU上電以來所經過的刻度數。由於目前的CPU主頻都非常高,因此這個組件可以達到納秒級的計時精度。這個精確性是上述兩種方法所無法比擬的。在Pentium以上的CPU中,提供了一條機器指令RDTSC(Read Time Stamp Counter)來讀取這個時間戳記的數字,並將其儲存在EDX:EAX寄存器對中*/long GetCPUFreq() //擷取CPU頻率,單位: MHZ{int start,over;_asm {RDTSCmov start,eax}Sleep(50);_asm {RDTSCmov over,eax}return (over-start)/50000;}/* 把eax = 0作為輸入參數,可以得到CPU的製造商資訊。 cpuid指令執行以後,會返回一個12字元的製造商資訊, 前四個字元的ASC碼按低位到高位放在ebx,中間四個放在edx,最後四個字元放在ecx。*/string GetManID() //擷取製造商資訊{char ID[25]; memset(ID,0,sizeof(ID));ExeCPUID(0); //初始化memcpy(ID+0,&debx,4); //製造商資訊複製到數組memcpy(ID+4,&dedx,4);memcpy(ID+8,&decx,4);return string(ID);}/* 在我的電腦上點擊右鍵,選擇屬性,可以在視窗的下面看到一條CPU的資訊,這就是CPU的商標字串。CPU的商標字串也是通過cpuid得到的。由於商標的字串很長(48個字元),所以不能在一次cpuid指令執行時全部得到,所以intel把它分成了3個操作,eax的輸入參數分別是0x80000002,0x80000003,0x80000004,每次返回的16個字元,按照從低位到高位的順序依次放在eax, ebx, ecx, edx。因此,可以用迴圈的方式,每次執行完以後儲存結果,然後執行下一次cpuid。*/string GetCPUType(){const DWORD id = 0x80000002; //從0x80000002開始,到0x80000004結束char CPUType[49];//用來儲存CPU型號資訊memset(CPUType,0,sizeof(CPUType));//初始化數組for(DWORD t = 0 ; t < 3 ; t++ ){ExeCPUID(id+t);//每次迴圈結束,儲存資訊到數組memcpy(CPUType+16*t+ 0,&deax,4);memcpy(CPUType+16*t+ 4,&debx,4);memcpy(CPUType+16*t+ 8,&decx,4);memcpy(CPUType+16*t+12,&dedx,4);}return string(CPUType);}void main() { cout<<"本機CPU資訊如下:"<<endl;cout<<"CPU 主 頻: "<<GetCPUFreq()<<" MHZ"<<endl;cout<<"CPU 製造商: "<<GetManID()<<endl;cout<<"CPU 型 號: "<<GetCPUType()<<endl;cin.get();}