如何获取多核、多cpu系统中指定cpu的序列号

    技术2022-05-11  65

    如何获取多核、多cpu系统中指定cpu的序列号 作者:SkyJacker (转贴请保持完整并注明作者和出处)

    http://www.cnpack.orgCnPack IV  QQ Group: 1309702007-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     EBXend;

    //获取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不适合你''你在你短暂的生命里花大量的时间去做这个没有价值的事情'

     

    最新回复(0)