CPUID
近两天研究了下CPUID指令。虽然原本是准备作为加密技术的储备的,不过后来发现作为加密技术实在不可行,倒是平台识别有很大用途。
CPUID指令可以看做一个汇编中的函数,预先设定一个EAX的编号,就可以返回EAX,EBX,ECX,EDX四个数据。根据不同EAX,返回不同的数据。问题在于,对于EAX和返回的约定上,AMD和Intel是完全不同的。其中AMD根本不支持CPU编号特性。
我先给出我所用的函数:
void getCpuID (PDWORD pData, DWORD ID)
{
__asm {
push ebx
push ecx
push edx
push esi
mov eax, ID
cpuid
mov esi, pData
mov [esi], eax
mov [esi+4], ebx
mov [esi+8], ecx
mov [esi+12], edx
pop esi
pop ecx
pop ebx
pop edx
}
}
其中pData是一个足够大的数组,ID是入口编号。根据Intel和AMD的约定,0,1,80000001-80000003是共同的。0在EBX,EDX,ECX中返回了厂商标识,例如目前机器上就是AuthenticAMD。(注意,不是顺序存放的,按照我刚刚写的顺序)80000001-80000003在返回中顺序存放了CPU的标识,例如目前机器上是AMD Sempron(tm) Processor 2500+。1在EAX中返回了CPU的系列编号,EDX中返回了特性编号。以上都是标准的返回,可以看出在识别平台的时候很方便。
Intel的CPU在2中存放了配置参数,3中存放了序列编号。而AMD在这两者上都是0。由此大家就知道为什么无法用来作为加密技术了,难道这个程序只能在Intel芯片上跑吗?