如何獲取多核、多cpu系統中指定cpu的序列號


如何獲取多核、多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    
    
以下三個函數,可供參考:

 

[c-sharp]  view plain copy
 
  1. function NewCPUID: string;  
  2. const  
  3.   CPUINFO = 'CPU制造商: %S  序列號: %x';  
  4. var  
  5.   s: array[0..19] of Char;  
  6.   MyCpuID: Integer;  
  7. begin  
  8.   FillChar(s, 20, 0);  
  9.   asm  
  10.     push ebx  
  11.     push ecx  
  12.     push edx  
  13.     mov  eax, 0  
  14.     cpuid  
  15.     mov  dword  ptr  s[0],    ebx  
  16.     mov  dword  ptr  s[4],    edx  
  17.     mov  dword  ptr  s[8],    ecx  
  18.     mov  eax,  1  
  19.     cpuid  
  20.     mov  MyCpuID,  edx  
  21.     pop edx  
  22.     pop ecx  
  23.     pop ebx  
  24.   end;  
  25.   Result := Format(CPUINFO, [s, MyCpuID]);  
  26. end;   
  27.   
  28. function GetCPUID: TCPUID; assembler; register;  
  29. asm  
  30.   PUSH    EBX         {Save affected register}  
  31.   PUSH    EDI  
  32.   MOV     EDI, EAX    [email={@Resukt]{@Resukt[/email]}  
  33.   MOV     EAX, 1  
  34.   DW      $A20F       {CPUID Command}  
  35.   STOSD               {CPUID[1]}  
  36.   MOV     EAX, EBX  
  37.   STOSD               {CPUID[2]}  
  38.   MOV     EAX, ECX  
  39.   STOSD               {CPUID[3]}  
  40.   MOV     EAX, EDX  
  41.   STOSD               {CPUID[4]}  
  42.   POP     EDI         {Restore registers}  
  43.   POP     EBX  
  44. end;   
  45.   
  46. //獲取cpu的序列號:  
  47.   
  48. function GetCnCPUID(): string;  
  49. const  
  50.   CPUINFO = '%.8x-%.8x-%.8x-%.8x';  
  51. var  
  52.   iEax: Integer;  
  53.   iEbx: Integer;  
  54.   iEcx: Integer;  
  55.   iEdx: Integer;  
  56. begin  
  57.   asm  
  58.     push ebx  
  59.     push ecx  
  60.     push edx  
  61.     mov  eax, 1  
  62.     DW $A20F//cpuid  
  63.     mov  iEax, eax  
  64.     mov  iEbx, ebx  
  65.     mov  iEcx, ecx  
  66.     mov  iEdx, edx  
  67.     pop edx  
  68.     pop ecx  
  69.     pop ebx  
  70.   end;  
  71.   Result := Format(CPUINFO, [iEax, iEbx, iEcx, iEdx]);  
  72. end;  

 

2、如何獲取指定cpu或指定cpu核的序列號。

根據Windows可以設置進程和線程的親緣性的特點,使用SetProcessAffinityMask函數,來控制哪個cpu來運行獲取序列號的進程,因此也就獲取了指定的cpu的序列號。為了和單cpu兼容,建議總是獲取第一個cpu的序列號。

 

[c-sharp]  view plain copy
 
  1. procedure SetCPU(h: THandle;CpuNo: Integer);  
  2. //CpuNo:決定了獲得第幾個cpu內核的第幾個序列號。  
  3. var  
  4.   ProcessAffinity: Cardinal;  
  5.   _SystemAffinity: Cardinal;  
  6. begin  
  7.     GetProcessAffinityMask(h, ProcessAffinity, _SystemAffinity) ;  
  8.     ProcessAffinity := CpuNo; //this sets the process to only run on CPU 0  
  9.                               //for CPU 1 only use 2 and for CPUs 1 & 2 use 3  
  10.     SetProcessAffinityMask(h, ProcessAffinity)  
  11. 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM