CPUID指令有两套函数,第一套函数返回处理器的基本信息,第二套函数返回处理器的扩展信息。图一总结了CPUID指令所能输出的处理器的基本信息。CPUID指令的输出完全依赖于EAX寄存器的内容,根据EAX寄存器中的值,执行CPUID指令时会调用不同的函数(见表一)。
为了确定CPUID指令输出处理器的基本信息时,EAX寄存器所能接受的最大的输入值,应用程序应该将EAX寄存器赋值为0并执行CPUID指令:
MOV EAX, 00H
CPUID
执行完后结果会保存在EAX寄存器中,为了返回有效的CPU基本信息,应该总是给EAX寄存器传递大于等于0并小于等于该结果的值。
为了确定CPUID指令输出处理器的扩展信息时,EAX寄存器所能接受的最大的输入值,应用程序应该将EAX寄存器赋值为80000000h并执行CPUID指令:
MOV EAX, 80000000H
CPUID
执行完成后结果会保存在EAX寄存器中,为了返回有效的CPU扩展信息,应该总是给EAX寄存器传递大于等于80000000h并小于等于该结果的值。
在任何一种情况下,如果给EAX传递的值大于其所能接受的最大值,或者返回扩展信息的函数不被支持的话,执行完CPUID指令后,EAX寄存器的最高位都会被清零,其它位的数值由具体的处理器模型指定(moel specific),并且是不可信赖的。
一、厂商ID字符串(Vendor ID String)
除了EAX寄存器所能接受的最大值,CPUID指令还能够同时返回处理器的厂商ID字符串(Verdor ID String)。当给EAX寄存器传递0作为输入值时,EBX、EDX和ECX寄存器中会保存厂商ID字符串,见图一。该信息为ASCII码字符串:
GenuineIntel(*)
任何INTEL处理器架构的模仿者都可以支持CPUID指令,但他们确不能正当地宣称其架构为真正的INTEL架构。因此,这个字符串是一个保证,它能够确保基于它的CPUID指令和处理器签名完全符合本文档中的说明。如果返回的字符串不是“GenuineIntel”,则不能根据本文档中的描述对实际返回的字符串进行解释。
图一
| ||||||||||||||||||||||||||||||||||||
表一 |
二、处理器签名(Processor Signature)
从INTEL486处理器家族开始,EDX寄存器在复位后保存了处理器鉴别签名(Processor Identification Signature),见图二。处理器鉴别签名是一个32位的值,由八个位域组成。灰色的位域代表保留位,在使用处理器签名的时候应该被排除在外(masked out)。剩余的六个位域构成了处理器鉴别签名。
图二
实现了CPUID指令的处理器也会在复位后返回处理器,不过使用CPUID指令更灵活,可以随时检查处理器签名,就是说不需要复位也能查看。图二展示了INTEL486及后续处理器的签名格式。值得注意的是,复位后EDX中返回的处理器签名和图一中EAX中输出的处理器签名是相同的。
上图中,第20位到27位的Extended Family,用于和第8位到第11位的Family Code连接起来,表明处理器属于INTEL386、486、Pentium、Pentium Pro还是Pentium 4。Pentium 6家族包括所有基于Pentium Pro架构的处理器型号,并且其Extended Family值为00h,Family Code值为6h。Pentium 4家族包括所有基于NetBurst架构的处理器,并且其Extended Family值为00h,Family Code值为0fh。
Extended Model和Model Number联合起来标示处理器家族中的处理器模型。Stepping ID表示该模型的修订版本号。
第十二位和第十三位指定处理器类型,包括原生OEM处理器、超速处理器(OverDrive Processor)以及双核处理器(Dual Processor)。表二展示了Type所代表的处理器类型。
Value | Type |
00 | 原生OEM处理器 |
01 | 超速处理器 |
10 | 双核处理器 |
11 | Intel保留 (不能使用) |
Model值为5的奔腾II处理器、奔腾II至强处理器和赛扬处理器,共享相同的Extended Family、Family Code、Extended Model和Model Number。为了区分这几种处理器,应用程序应该使用检查缓存的大小,方法是使EAX=2,然后调用CPUID指令。如果不返回二级缓存的描述信息,则使用的是赛扬处理器;如果返回的二级缓存大小为1M或者2M,则CPU为奔腾II至强处理器;不然就是二级缓存为512K的奔腾II至强处理器或者奔腾II处理器。
属于Model 7的奔腾III处理器和奔腾III至强处理器,它们也共享相同的Extended Family、Family Code、Extended Model和Model Number。为了区分这几种处理器,应用程序应该使用检查缓存的大小,方法是是EAX=2,然后调用CPUID指令。如果不返回二级缓存的描述信息,则使用的是奔腾III至强处理器;如果返回的二级缓存大小为1M或者2M,则CPU为奔腾III至强处理器;不然就是二级缓存为512K的奔腾III至强处理器或者奔腾III处理器。
Model值为8的奔腾III处理器、奔腾III至强处理器以及赛扬处理器,它们的处理器商标(Processor brand)可以通过Brand ID来确定,方法是使EAX=1,然后调用CPUID指令。
更早版本的处理器,诸如Intel486 SX, Intel486 DX和IntelDX2™,并不支持CPUID指令,因此它们的处理器签名只能在处理器复位后查看。
图三展示了INTEL 386处理器签名的格式,这种格式跟其它处理器不同。
图三