如何获取多核、多cpu系统中指定cpu的序列号作者:SkyJacker(转贴请保持完整并注明作者和出处)http://www.cnpack.org在多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 //获取制造商信息cpuidmov eax, 1 //获得CPU的序列号cpuid 以下三个函数,可供参考:
function NewCPUID: string;constCPUINFO = 'CPU制造商: %S 序列号: %x';vars: array[0..19] of Char;MyCpuID: Integer;beginFillChar(s, 20, 0);asmpush ebxpush ecxpush edxmov eax, 0cpuidmov dword ptr s[0], ebxmov dword ptr s[4], edxmov dword ptr s[8], ecxmov eax, 1cpuidmov MyCpuID, edxpop edxpop ecxpop ebxend;Result := Format(CPUINFO, [s, MyCpuID]);end;
function GetCPUID: TCPUID; assembler; register;asmPUSH EBX {Save affected register}PUSH EDIMOV EDI, EAX [email={@Resukt]{@Resukt[/email]}MOV EAX, 1DW $A20F {CPUID Command}STOSD {CPUID[1]}MOV EAX, EBXSTOSD {CPUID[2]}MOV EAX, ECXSTOSD {CPUID[3]}MOV EAX, EDXSTOSD {CPUID[4]}POP EDI {Restore registers}POP EBXend;
//获取cpu的序列号:
function GetCnCPUID(): string;constCPUINFO = '%.8x-%.8x-%.8x-%.8x';variEax: Integer;iEbx: Integer;iEcx: Integer;iEdx: Integer;beginasmpush ebxpush ecxpush edxmov eax, 1DW $A20F//cpuidmov iEax, eaxmov iEbx, ebxmov iEcx, ecxmov iEdx, edxpop edxpop ecxpop ebxend;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内核的第几个序列号。varProcessAffinity: Cardinal;_SystemAffinity: Cardinal;beginGetProcessAffinityMask(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 3SetProcessAffinityMask(h, ProcessAffinity)end;
使用方法:
SetCPU(GetCurrentProcess,1); //第一个cpu的第一个cpu内核ShowMessage(GetCnCPUID);