如何獲取多核、多cpu系統中指定cpu的序列號
作者:SkyJacker
(轉貼請保持完整並注明作者和出處)
http://www.cnpack.org
CnPack IV QQ Group: 130970
2007-01-23
感謝:Passion,Bahamut,早安,空氣,SkyJacker...
沒有Bahamut的奇思妙點,就沒有這片文章。
在多cpu、多核中,會隨機的獲得不同的序列號.這就為我們根據cpu序列號來制作注冊機帶來了很大的麻煩。
Windows 2000/xp允許設置進程和線程的親緣性。換句話說,可以控制哪個 CPU 能夠運行某些線程。這稱為硬親緣性。Windows提供了設置親緣性的函數SetProcessAffinityMask 。使用它可控制獲取指定cpu的序列號。
本文分為2部分:
1、如何獲得cpu的序列號。
2、如何獲取指定cpu或指定cpu核的序列號。
1、如何獲得cpu的序列號。
使用cpuid指令來獲取。
在調用CPUID之前,EAX中存放的是功能代碼。在調用CPUID之后,EAX,EBX,ECX,EDX存放的是CPU的各種特征信息。這些信息也就是我們通常所說的CPU序列號。
mov eax, 0 //獲取制造商信息
cpuid
mov eax, 1 //獲得CPU的序列號
cpuid
以下三個函數,可供參考:
- function NewCPUID: string;
- const
- CPUINFO = 'CPU制造商: %S 序列號: %x';
- var
- s: array[0..19] of Char;
- MyCpuID: Integer;
- begin
- FillChar(s, 20, 0);
- asm
- push ebx
- push ecx
- push edx
- mov eax, 0
- cpuid
- mov dword ptr s[0], ebx
- mov dword ptr s[4], edx
- mov dword ptr s[8], ecx
- mov eax, 1
- cpuid
- mov MyCpuID, edx
- pop edx
- pop ecx
- pop ebx
- end;
- Result := Format(CPUINFO, [s, MyCpuID]);
- end;
- function GetCPUID: TCPUID; assembler; register;
- asm
- PUSH EBX {Save affected register}
- PUSH EDI
- MOV EDI, EAX [email={@Resukt]{@Resukt[/email]}
- MOV EAX, 1
- DW $A20F {CPUID Command}
- STOSD {CPUID[1]}
- MOV EAX, EBX
- STOSD {CPUID[2]}
- MOV EAX, ECX
- STOSD {CPUID[3]}
- MOV EAX, EDX
- STOSD {CPUID[4]}
- POP EDI {Restore registers}
- POP EBX
- end;
- //獲取cpu的序列號:
- function GetCnCPUID(): string;
- const
- CPUINFO = '%.8x-%.8x-%.8x-%.8x';
- var
- iEax: Integer;
- iEbx: Integer;
- iEcx: Integer;
- iEdx: Integer;
- begin
- asm
- push ebx
- push ecx
- push edx
- mov eax, 1
- DW $A20F//cpuid
- mov iEax, eax
- mov iEbx, ebx
- mov iEcx, ecx
- mov iEdx, edx
- pop edx
- pop ecx
- pop ebx
- end;
- Result := Format(CPUINFO, [iEax, iEbx, iEcx, iEdx]);
- end;
2、如何獲取指定cpu或指定cpu核的序列號。
根據Windows可以設置進程和線程的親緣性的特點,使用SetProcessAffinityMask函數,來控制哪個cpu來運行獲取序列號的進程,因此也就獲取了指定的cpu的序列號。為了和單cpu兼容,建議總是獲取第一個cpu的序列號。
- procedure SetCPU(h: THandle;CpuNo: Integer);
- //CpuNo:決定了獲得第幾個cpu內核的第幾個序列號。
- var
- ProcessAffinity: Cardinal;
- _SystemAffinity: Cardinal;
- begin
- GetProcessAffinityMask(h, ProcessAffinity, _SystemAffinity) ;
- ProcessAffinity := CpuNo; //this sets the process to only run on CPU 0
- //for CPU 1 only use 2 and for CPUs 1 & 2 use 3
- SetProcessAffinityMask(h, ProcessAffinity)
- end;
使用方法:
SetCPU(GetCurrentProcess,1); //第一個cpu的第一個cpu內核
ShowMessage(GetCnCPUID);
后記:這片文章源於CnPack 群里關於獲取多核CPU的ID的問題討論。
感謝CnPack 群里的所有成員。
BS下'早安空氣',竟然說“你在你短暫的生命里花大量的時間去做這個沒有價值的事情”-_-!!超級BS、BS、BS……^_^
for I:=0 to 10000000000000000000000000000 do
BS;
附錄“早安空氣”語錄:
'放棄吧,API不適合你'
'你在你短暫的生命里花大量的時間去做這個沒有價值的事情'
參考:http://blog.csdn.net/iseekcode/article/details/5284803