CPUID 是 啥?
CPUID 是 80486 CPU 以后,在 x86 指令集所新增的一个指令,它的用途在于鑑别 CPU 种类或提供 CPU 特性。在 80386 末期,CPU 两大制造厂商,INTEL 与 AMD,常推出时脉更高速度更快的 CPU 相互竞争,这本是件好事,但有不肖厂商把较低时脉的 CPU 上的标籤磨掉后重新印制较高时脉的字样,藉此鱼目混珠获取不义之财。
小木偶记得那时还有许多文献探讨,是否能利用 CPU 的某些特性来分辨 CPU 以及是否有方法能辨识 CPU 时脉,前者常常只能分辨 8088、80286、80386 等这种不同世代的 CPU,甚至无法区分不同厂商所制作的 CPU。至于后者到目前似乎是无解的。后来 CPU 『型号』日益复杂,如果只是靠 CPU 某些特性来辨识,实在是一件不易达成的目标。因此,INTEL 在 80486 CPU 指令集中新增一个指令,CPUID,来辨识 CPU 型号,不仅仅如此,它还详细的列制造厂商、时脉、快取等等资料,所以 CPUID 可说是 CPU 的身分证。
检查 CPU 能否执行 CPUID?
并不是所有的 CPU 都能执行 CPUID 指令,例如 8086/88、80286、80386,当然啦,现在大概也找不到这些 CPU 了,不过还是把检查的方法说一说。根据英特尔文献,Intel? Processor Identification and the CPUID Instruction,的记载,如果 CPU 延伸旗标 ( EFLAG ) 的第 21 位元 ( 称为 ID ) 可以由软体写入的话,那么你的 CPU 可以执行 CPUID。底下是一段检查的程式码:
;如果程式可以改变 EFLAGE 的第 21 位元,那么 CPUID 有效,否则无效
pop eax ;把堆叠中的延伸旗标弹出至 EAX
mov ecx,eax ;保存旧的延伸旗标
xor eax,200000h ;改变强制延伸旗标第 21 位元
push eax ;把改变后新的延伸旗标推入堆叠
popfd ;存入延伸旗标
pushfd ;再取出延伸旗标
pop eax
xor eax,ecx ;如果延伸旗标的第21位元为1,那么
jz no_cpuid ;CPUID存在,否则不存在
……可以执行 CPUID 指令……
no_cpuid:
……不能执行 CPUID 指令……
LAHF/SAHF 指令
在 80x86 指令集中有一个指令可以直接取得旗标暂存器之值,它是 LAHF,LAHF 把延伸旗标暂存器的最低八位元存入 AH 暂存器里。SAHF 是把 AH 之值存入延伸暂存器的最低八个位元,。下图是 8086/8088 旗标暂存器各位元分布:
由图上可知,SAHF 会影响 CF、PF、AF、ZF、SF 五个旗标,LAHF 是把旗标暂存器之值存入 AH 中,因此不影响原来的旗标。SAHF、LAHF 不需要运算元,其语法是:
SAHF
LAHF
虽然 LAHF 能直接取得旗标暂存器,但是对于要存取延伸旗标的 ID 位元却毫无帮助,只好藉助堆叠。
PUSHF/POPF 与 PUSHFD/POPFD 指令
PUSHF 是把 16 位元的 8086/8088 旗标暂存器推入堆叠,而 POPF 则是把堆叠顶的 16 位元资料弹出到 16 位元的旗标暂存器。PUSHFD 则是把 32 位元的 EFLAG 推入堆叠,32 位元的长度是双字组,PUSHFD 的『D』是 double word 之意;POPFD 则是把堆叠顶的双字组弹出到 EFLAG。这四个指令,也都不须运算元。
--------------------------------------------------------------------------------
CPUID 介绍
要利用 CPUID 指令获得 CPU 资料,一般是以 EAX 当做索引值,所给定的 EAX 索引值不同,就可以获得不同的 CPU 资料。这些索引值可分为两大类:基本功能 ( standard function ) 与延伸功能 ( extended function ) ,基本功能的 EAX 索引值最高位元为零,延伸功能的最高位元为 1,不管是那一家公司所生产的 x86 处理器,基本功能或延伸功能都有好几个,所以得先取得基本功能或延伸功能的最大索引值。一般是先把 EAX 设为 0,然后执行 CPUID,就可以在 EAX 中得到基本功能的最大索引值;而要获得延伸功能的最大索引值,先使 EAX 设为 80000000H,再执行 CPUID,在返回时,EAX 就存有最大延伸功能的索引值。得到最大索引值后,EAX 就应该在这个最大值内去『呼叫』CPUID,如果你用比最大索引值还大的数值存于 EAX,去执行 CPUID,结果和以最大索引值一样。
EAX=0000 0000
当 EAX 等于 0 再执行 CPUID 后,CPUID 会传回两笔资料,第一笔资料是存放在 EAX,EAX 会传回基本功能的最大索引值,第二笔资料存放在 EBX、ECX、EDX 共 96 位元,它们共同表示制造厂商的名称字串,如果是英特尔的 CPU,其分布如下图:
EAX 的返回值
EAX 表示 CPU 的等级 ( Family )、核心 ( Model ) 与工艺制成 ( Stepping ),下图为 EAX 的返回值,各位元所代表的意义:
依据英特尔手册,CPU 的 Family 应该是 EAX 中的 Family Code 与 Extended Family 之和,Model 是 Extended Model 左移 4 位元之后再加上 Model Number 之值。一般而言,Family 代表同一代生产的 CPU,大致可分为:
Family=4:包含 80486DX、80486SX、80486DX2……
Family=5:包含 Pentium、Pentium MMX、AMD K5、AMD K6、K6-2、K6-III……
Family=6:包含 Pentium II、Pentium !!!、Pentium Pro、CeleronA、Pentium M、Core 2 Duo、Athlon、Athlon XP……
Family=F:包含 Pentium 4、Pentium D、Pentium Extreme Edition、Athlon 64、Sempron、Opteron、Athlon 64 X2……
Model 用来区别同一代但不同核心的 CPU,例如:
Pentium 60、66MHz 最早期 ( 民国 82 年 ) 的核心是 P5 ( Model 是 1 ),接著发展出 P54C 核心 ( Model 是 2 ),到了民国 86 年,出产核心 P55C,Model 为 4 的 Pentium MMX。
Pentium II 有 Klamath、Deschutes 两种核心,其 Model 分别是 3、5。
Pentium II Celeron 也有两种核心 Covington、Mendocino,其 Model 分别是 5、6。
Pentium !!! 有 Katmai、Coppermine、Tualatin 三种核心,其 Model 分别是 7、8、0FH,前者是 Slot 1插槽,后两者是 Socket 370 插槽。
Athlon 有 Argon、Pluto、Thunderbird 不同核心,其 Model 分别是 1、2、4。
Athlon XP 有 Palomino、Thoroughbred、Barton 三种不同核心,其 Model 分别是 6、8、A。
Stepping 表示同一核心不同工艺的产品,例如:
Pentium II 的 Klamath 核心,先后有两种工艺制品,C0、C1,其 Stepping 分别是 3、4。
Pentium II 的 Klamath 核心,有三种工艺产品,dA0、dA1、dB0、dB1,其 Stepping 分别是 0、1、2、3。
EBX 的返回值
下表是英特尔的 CPU 以 EAX=1 为参数,EBX 的返回值,对 AMD 的 CPU 来说,大致相同,只有位元 4~12 和 14~22 均保留不用。
位元 | 名稱 | 說 明 此位元為 1 時 |
0~7 | Brand ID | 在 Pentium !!! 的時代裏,開始用 Brand ID 來補足 Family、Model、Stepping 的不足,因此目前為止,要辨識 CPU『身分』,必須用這四筆資料來判斷。 |
8~15 | Chunks | |
16~23 | Count | |
24~31 | APIC ID |
ECX 的返回值
下表是英特尔的 CPU 以 EAX=1 为参数,ECX 的返回值,对 AMD 的 CPU 来说,大致相同,只有位元 4~12 和 14~22 均保留不用。
位元 | 縮写 | 名称 | 说明 此位元為 1 時 |
0 | SSE3 | Streaming SIMD Extensions 3 | 支援 Streaming SIMD Extensions 3 指令集 |
1~2 | 保留 | ||
3 | MONITOR | MONITOR/MWAIT | 支援 MONITOR 與 MWAIT 指令 |
4 | DS-CPL | CPL Qualified Debug Store | |
5 | VMX | Virtual Machine Extensions | 支援 Virtualization 技術 |
6 | 保留 | ||
7 | EST | Enhanced Intel SpeedStep® Technology | 提供第二代的 SpeedStep 技術 |
8 | TM2 | Thermal Monitor 2 | 提供 Thermal Monitor 2 |
9 | SSSE3 | Supplemental Streaming SIMD Extension 3 | 支援 SSSE3 指令集 |
10 | CID | Context ID | 第一階快取可被 BIOS 設為 adaptive 或 shared 模式 |
11~12 | 保留 | ||
13 | CX16 | CMPXCHG16B | 支援 CMPXCHG16B 指令 |
14 | xTPR | Send Task Priority Message | |
15~17 | 保留 | ||
18 | DCA | Direct Cache Access | |
19~31 | 保留 |
待续 。。。