近两天研究了下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芯片上跑吗?