研究心得——->CPU信息的获得,比较全面的。

研究心得——->CPU信息的获得,比较全面的。

转自我的旧博客.

最近到整理了一份CPU的信息,应该算是比较全面的吧。
几乎现在所有的X86 CPU都内置了CPUID指令以辨别真伪,一些CPU厂商例如AMD,VIA等还内置了更加丰富的扩展CPUID指令,用着更方便了。
下面我们利用Delphi来实现一个CPU检测的软件。
CPUID的调用方式如下:
asm
push eax
push ebx
push ecx
push edx
mov eax,X
//******************************************************
//cpuid指令,因为Delphi的汇编编译器没有内置该指令,
//所以用该指令的机器语言代码$0F,$A2来实现
//******************************************************
db $0F,$A2
pop edx
pop ecx
pop ebx
pop eax
end;
CPUID指令的参数就是EAX,mov eax,X这一句就是把X赋给EAX 。
返回的参数存储在EAX,EBX,ECX,EDX之中。
我们可以写一个函数:
type
TCPUIDResult = record
EAX: DWord;
EBX: DWord;
ECX: DWord;
EDX: DWord;
end;
……
function CPUID(EAX:DWord): TCPUIDResult;
asm
push eax
push ebx
push ecx
push edx
mov eax,EAX
//******************************************************
//cpuid指令,因为Delphi的汇编编译器没有内置该指令,
//所以用该指令的机器语言代码$0F,$A2来实现
//******************************************************
db $0F,$A2
mov Result.EAX,EAX
mov Result.EBX,EBX
mov Result.ECX,ECX
mov Result.EDX,EDX
pop edx
pop ecx
pop ebx
pop eax
end;

CPUID参数及返回值列表:
EAX= 0000_0000h
输入 ?EAX=0000_0000h ?得到CPUID指令所支持的最大值和厂家的名称字符串
输出 ?EAX=xxxx_xxxxh ?得到CPUID指令所支持的最大值 #1
EBX-EDX-ECX ?厂家的名称字符串 #2
GenuineIntel ?Intel 处理器
UMC UMC UMC ?UMC 处理器
AuthenticAMD ?AMD 处理器
CyrixInstead ?Cyrix 处理器
NexGenDriven ?NexGen 处理器
CentaurHauls ?Centaur 处理器
RiseRiseRise ?Rise Technology 处理器
GenuineTMx86 ?Transmeta 处理器
Geode by NSC ?National Semiconductor 处理器
说明 ?描述
#1 ?pre-B0 step Intel P5 处理器返回 EAX=0000_05xxh.
#2 ?pre-B0 step Intel P5 处理器不能返回厂商字符串
EAX= 0000_0001h
输入 ?EAX=0000_0001h ?得到处理器 type/family/model/stepping和 面貌标识
输出 ?EAX=xxxx_xxxxh ?处理器 type/family/model/stepping
extended family ?extended family 是 bits 27..20.
00h ?Intel P4
01h ?Intel Itanium 2 (IA-64)
extended model ?extended model 是 bits 19..16.
type ?type是 bit 13 和 bit 12.
11b ?保留
10b ?第二块处理器
01b ?Overdrive 处理器
00b ?第一处理器
family ?family是bits 11..8.
4 ?most 80486s
AMD 5×86
Cyrix 5×86
5 ?Intel P5, P54C, P55C, P24T
NexGen Nx586
Cyrix M1
AMD K5, K6
Centaur C6, C2, C3
Rise mP6
Transmeta Crusoe TM3x00 and TM5x00
6 ?Intel P6, P2, P3
AMD K7
Cyrix M2, VIA Cyrix III
7 ?Intel Itanium (IA-64)
F ?如果是这个值的话就看extended family
model ?model 是 bits 7..4.
Intel ?F ?如果是这个值的话就看 extended model
Intel 80486 ?0 ?i80486DX-25/33
1 ?i80486DX-50
2 ?i80486SX
3 ?i80486DX2
4 ?i80486SL
5 ?i80486SX2
7 ?i80486DX2WB
8 ?i80486DX4
9 ?i80486DX4WB
UMC 80486 ?1 ?U5D
2 ?U5S
AMD 80486 ?3 ?80486DX2
7 ?80486DX2WB
8 ?80486DX4
9 ?80486DX4WB
E ?5×86
F ?5x86WB
Cyrix 5×86 ?9 ?5×86
Cyrix MediaGX ?4 ?GX, GXm
Intel P5-core ?0 ?P5 A-step
1 ?P5
2 ?P54C
3 ?P24T Overdrive
4 ?P55C
7 ?P54C
8 ?P55C (0.25μm)
NexGen Nx586 ?0 ?Nx586 or Nx586FPU (only later ones)
Cyrix M1 ?2 ?6×86
Cyrix M2 ?0 ?6x86MX
VIA Cyrix III ?5 ?Cyrix M2 core
6 ?WinChip C5A core
7 ?WinChip C5B core (if stepping = 0..7)
7 ?WinChip C5C core (if stepping = 8..F)
8 ?WinChip C5C-T core (if stepping = 0..7)
AMD K5 ?0 ?SSA5 (PR75, PR90, PR100)
1 ?5k86 (PR120, PR133)
2 ?5k86 (PR166)
3 ?5k86 (PR200)
AMD K6 ?6 ?K6 (0.30 μm)
7 ?K6 (0.25 μm)
8 ?K6-2
9 ?K6-III
D ?K6-2+ or K6-III+ (0.18 μm)
Centaur ?4 ?C6
8 ?C2
9 ?C3
Rise ?0 ?mP6 (0.25 μm)
2 ?mP6 (0.18 μm)
Transmeta ?4 ?Crusoe TM3x00 and TM5x00
Intel P6-core ?0 ?P6 A-step
1 ?P6
3 ?P2 (0.28 μm)
5 ?P2 (0.25 μm)
6 ?P2 with on-die L2 cache
7 ?P3 (0.25 μm)
8 ?P3 (0.18 μm)
with 256 KB on-die L2 cache
A ?P3 (0.18 μm)
with 1 or 2 MB on-die L2 cache
B ?P3 (0.13 μm)
with 256 or 512 KB on-die L2 cache
AMD K7 ?1 ?Athlon (0.25 μm)
2 ?Athlon (0.18 μm)
3 ?Duron (SF core)
4 ?Athlon (TB core)
6 ?Athlon (PM core)
7 ?Duron (MG core)
8 ?Athlon (TH core)
A ?Athlon (Barton core)
Intel P4-core ?0 ?P4 (0.18 μm)
1 ?P4 (0.18 μm)
2 ?P4 (0.13 μm)
3 ?P4 (0.09 μm)
stepping ?stepping 在 bits 3..0.
Stepping描述的是处理器的细节.
EBX=aall_ccbbh ?brand ID ?brand ID是 7..0.
00h ?不支持
01h ?0.18 μm Intel Celeron
02h ?0.18 μm Intel Pentium III
03h ?0.18 μm Intel Pentium III Xeon
03h ?0.13 μm Intel Celeron
04h ?0.13 μm Intel Pentium III
07h ?0.13 μm Intel Celeron mobile
06h ?0.13 μm Intel Pentium III mobile
0Ah ?0.18 μm Intel Celeron 4
08h ?0.18 μm Intel Pentium 4
09h ?0.13 μm Intel Pentium 4
0Eh ?0.18 μm Intel Pentium 4 Xeon
0Bh ?0.18 μm Intel Pentium 4 Xeon MP
0Bh ?0.13 μm Intel Pentium 4 Xeon
0Ch ?0.13 μm Intel Pentium 4 Xeon MP
08h ?0.13 μm Intel Celeron 4 mobile
0Eh ?0.13 μm Intel Pentium 4 mobile (production)
0Fh ?0.13 μm Intel Pentium 4 mobile (samples)
CLFLUSH ?CLFLUSH (8-byte)在 bits 15..8.
CPU count ?逻辑处理器数量 bits 23..16.
APIC ID ?默认(固定的)APIC ID是bits 31..24.
ECX=xxxx_xxxxh ?feature flags ?描述
bits 31…11 ?保留
bit 10 (CID) ?context ID: L1数据缓存能被设置成适应或共享模式
bit 9 ?保留
bit 8 (TM2) ?热量监控 2
bit 7 ?保留
bit 6 ?保留
bit 5 ?保留
bit 4 (DSCPL) ?CPL-qualified Debug Store
bit 3 (MON) ?监控器
bit 2 ?保留
bit 1 ?保留
bit 0 (SSE3) ?SSE3, MXCSR, CR4.OSXMMEXCPT, #XF, 如果FPU=1也支持 FISTTP
EDX=xxxx_xxxxh ?面貌标志 ?说明
bit 31 (PBE) ?Pending Break Event, STPCLK, FERR#, MISC_ENABLE MSR
bit 30 (IA-64) ?IA-64
bit 29 (TM) ?THERM_INTERRUPT, THERM_STATUS, and MISC_ENABLE MSRsxAPIC thermal LVT entry
bit 28 (HTT) ?Hyper-Threading Technology
bit 27 (SS) ?selfsnoop
bit 26 (SSE2) ?SSE2, MXCSR, CR4.OSXMMEXCPT, #XF
bit 25 (SSE) ?SSE, MXCSR, CR4.OSXMMEXCPT, #XF
bit 24 (FXSR) ?FXSAVE/FXRSTOR, CR4.OSFXSR
bit 23 (MMX) ?MMX
bit 22 (ACPI) ?THERM_CONTROL MSR
bit 21 (DTES) ?Debug Trace and EMON Store MSRs
bit 20 ?保留
bit 19 (CLFL) ?CLFLUSH
bit 18 (PSN) ?PSN (see standard EAX=l 0000_0003h), PSN_DISABLE MSR #1
bit 17 (PSE36) ?4 MB PDE bits 16..13, CR4.PSE
bit 16 (PAT) ?PAT MSR, PDE/PTE.PAT
bit 15 (CMOV) ?CMOVcc, if FPU=1 then also FCMOVcc/F(U)COMI(P)
bit 14 (MCA) ?MCG_*/MCn_* MSRs, CR4.MCE, #MC
bit 13 (PGE) ?PDE/PTE.G, CR4.PGE
bit 12 (MTRR) ?MTRR* MSRs
bit 11 (SEP) ?SYSENTER/SYSEXIT, SEP_* MSRs#2
bit 10 ?保留
bit 9 (APIC) ?APIC #3, #4
bit 8 (CX8) ?CMPXCHG8B #5
bit 7 (MCE) ?MCAR/MCTR MSRs, CR4.MCE, #MC
bit 6 (PAE) ?64bit PDPTE/PDE/PTEs, CR4.PAE
bit 5 (MSR) ?MSRs, RDMSR/WRMSR
bit 4 (TSC) ?TSC, RDTSC, CR4.TSD (doesn’t imply MSR=1)
bit 3 (PSE) ?PDE.PS, PDE/PTE.res, CR4.PSE, #PF(1xxxb)
bit 2 (DE) ?CR4.DE, DR7.RW=10b, #UD on MOV from/to DR4/5
bit 1 (VME) ?CR4.VME/PVI, EFLAGS.VIP/VIF, TSS32.IRB
bit 0 (FPU) ?FPU
说明 ?说明
#1 ?如果PSN无效PSN 面貌标志就是0.
#2 ?尽管Intel P6 处理器不支持 SEP,在这里仍然会虚报(真不知Intel是怎么想的).
#3 ?APIC无效那么APIC面貌标志就是0.
#4 ?早期AMD K5 处理器 (SSA5)会假报支持 PGE.
#5 ?处理器确实支持 CMPXCHG8B但默认却是报告不支持. 其实这是Windows NT的一个Bug.
EAX= 0000_0002h

输入 ?EAX=0000_0002h ?得到处理器配置描述
输出 ?EAX.15..8
EAX.23..16
EAX.31..24
EBX.0..7
EBX.15..8
EBX.23..16
EBX.31..24
ECX.0..7
ECX.15..8
ECX.23..16
ECX.31..24
EDX.0..7
EDX.15..8
EDX.23..16
EDX.31..24 ?配置描述
值 ?说明
00h ?null descriptor (=unused descriptor)
01h ?code TLB, 4K pages, 4 ways, 32 entries
02h ?code TLB, 4M pages, fully, 2 entries
03h ?data TLB, 4K pages, 4 ways, 64 entries
04h ?data TLB, 4M pages, 4 ways, 8 entries
06h ?code L1 cache, 8 KB, 4 ways, 32 byte lines
08h ?code L1 cache, 16 KB, 4 ways, 32 byte lines
0Ah ?data L1 cache, 8 KB, 2 ways, 32 byte lines
0Ch ?data L1 cache, 16 KB, 4 ways, 32 byte lines
10h ?data L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
15h ?code L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
1Ah ?code and data L2 cache, 96 KB, 6 ways, 64 byte lines (IA-64)
22h ?code and data L3 cache, 512 KB, 4 ways (!), 64 byte lines, dual-sectored
23h ?code and data L3 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
25h ?code and data L3 cache, 2048 KB, 8 ways, 64 byte lines, dual-sectored
29h ?code and data L3 cache, 4096 KB, 8 ways, 64 byte lines, dual-sectored
39h ?code and data L2 cache, 128 KB, 4 ways, 64 byte lines, sectored
3Bh ?code and data L2 cache, 128 KB, 2 ways, 64 byte lines, sectored
3Ch ?code and data L2 cache, 256 KB, 4 ways, 64 byte lines, sectored
40h ?no integrated L2 cache (P6 core) or L3 cache (P4 core)
41h ?code and data L2 cache, 128 KB, 4 ways, 32 byte lines
42h ?code and data L2 cache, 256 KB, 4 ways, 32 byte lines
43h ?code and data L2 cache, 512 KB, 4 ways, 32 byte lines
44h ?code and data L2 cache, 1024 KB, 4 ways, 32 byte lines
45h ?code and data L2 cache, 2048 KB, 4 ways, 32 byte lines
50h ?code TLB, 4K/4M/2M pages, fully, 64 entries
51h ?code TLB, 4K/4M/2M pages, fully, 128 entries
52h ?code TLB, 4K/4M/2M pages, fully, 256 entries
5Bh ?data TLB, 4K/4M pages, fully, 64 entries
5Ch ?data TLB, 4K/4M pages, fully, 128 entries
5Dh ?data TLB, 4K/4M pages, fully, 256 entries
66h ?data L1 cache, 8 KB, 4 ways, 64 byte lines, sectored
67h ?data L1 cache, 16 KB, 4 ways, 64 byte lines, sectored
68h ?data L1 cache, 32 KB, 4 ways, 64 byte lines, sectored
70h ?trace L1 cache, 12 KμOPs, 8 ways
71h ?trace L1 cache, 16 KμOPs, 8 ways
72h ?trace L1 cache, 32 KμOPs, 8 ways
77h ?code L1 cache, 16 KB, 4 ways, 64 byte lines, sectored (IA-64)
79h ?code and data L2 cache, 128 KB, 8 ways, 64 byte lines, dual-sectored
7Ah ?code and data L2 cache, 256 KB, 8 ways, 64 byte lines, dual-sectored
7Bh ?code and data L2 cache, 512 KB, 8 ways, 64 byte lines, dual-sectored
7Ch ?code and data L2 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
7Eh ?code and data L2 cache, 256 KB, 8 ways, 128 byte lines, sect. (IA-64)
81h ?code and data L2 cache, 128 KB, 8 ways, 32 byte lines
82h ?code and data L2 cache, 256 KB, 8 ways, 32 byte lines
83h ?code and data L2 cache, 512 KB, 8 ways, 32 byte lines
84h ?code and data L2 cache, 1024 KB, 8 ways, 32 byte lines
85h ?code and data L2 cache, 2048 KB, 8 ways, 32 byte lines
88h ?code and data L3 cache, 2048 KB, 4 ways, 64 byte lines (IA-64)
89h ?code and data L3 cache, 4096 KB, 4 ways, 64 byte lines (IA-64)
8Ah ?code and data L3 cache, 8192 KB, 4 ways, 64 byte lines (IA-64)
8Dh ?code and data L3 cache, 3096 KB, 12 ways, 128 byte lines (IA-64)
90h ?code TLB, 4K…256M pages, fully, 64 entries (IA-64)
96h ?data L1 TLB, 4K…256M pages, fully, 32 entries (IA-64)
9Bh ?data L2 TLB, 4K…256M pages, fully, 96 entries (IA-64)
值 ?描述
70h ?Cyrix specific: code and data TLB, 4K pages, 4 ways, 32 entries
74h ?Cyrix specific: ???
77h ?Cyrix specific: ???
80h ?Cyrix specific: code and data L1 cache, 16 KB, 4 ways, 16 byte lines
82h ?Cyrix specific: ???
84h ?Cyrix specific: ???
值 ?描述
others ?保留
举个例子有一块 P6 ?EAX=0302_0101h
EBX=0000_0000h
ECX=0000_0000h
EDX=0604_0A43h ?这块P6处理器包含4K/M code/data TLB,8+8 KB code/data L1 cache 和混合 512 KB code/data L2 cache.
说明 ?说明
#1 ?在多处理器系统中要特别注意,应该执行.
EAX=0000_0003h
输入 ?EAX=0000_0003h ?得到处理器序列号 #1
输出 ?EBX=xxxx_xxxxh ?处理器序列号(只只是Transmeta Crusoe)
ECX=xxxx_xxxxh ?处理器序列号
EDX=xxxx_xxxxh ?处理器序列号
说明 ?说明
#1 ?仅当PSN有效时.
EAX= 8000_0000h
输入 ?EAX=8000_0000h ?得到扩展CPUID指令所支持的最大值和厂家的名称字符串
输出 ?EAX=xxxx_xxxxh ?最大值
EBX-EDX-ECX ?厂家的名称字符串
AuthenticAMD ?AMD
保留 ?Cyrix
保留 ?Centaur
保留 ?Intel
TransmetaCPU ?Transmeta
保留 ?National Semiconductor
extended EAX= 8000_0001h
输入 ?EAX=8000_0001h ?得到处理器 family/model/stepping and features flags #0
输出 ?EAX=0000_0xxxh ?处理器 family/model/stepping
family ?Family是 bits 11..8.
5 ?AMD K5
Centaur C2
Transmeta Crusoe TM3x00 and TM5x00
6 ?AMD K6
VIA Cyrix III
7 ?AMD K7
model ?model 是bits 7..4.
AMD K5 ?1 ?5k86 (PR120 or PR133)
2 ?5k86 (PR166)
3 ?5k86 (PR200)
AMD K6 ?6 ?K6 (0.30 μm)
7 ?K6 (0.25 μm)
8 ?K6-2
9 ?K6-III
D ?K6-2+ or K6-III+ (0.18 μm)
AMD K7 ?1 ?Athlon (0.25 μm)
2 ?Athlon (0.18 μm)
3 ?Duron (SF core)
4 ?Athlon (TB core)
6 ?Athlon (PM core)
7 ?Duron (MG core)
8 ?Athlon (TH core)
A ?Athlon (Barton core)
Centaur ?8 ?C2
9 ?C3
VIA Cyrix III ?5 ?Cyrix M2 core
6 ?WinChip C5A core
7 ?WinChip C5B core (if stepping = 0..7)
7 ?WinChip C5C core (if stepping = 8..F)
8 ?WinChip C5C-T core (if stepping = 0..7)
Transmeta ?4 ?Crusoe TM3x00 and TM5x00
stepping ?stepping是bits 3..0.
Stepping的值是处理器的细节.
EDX=xxxx_xxxxh ?feature flags ?description of indicated feature
bit 31 (3DNow!) ?3DNow!
bit 30 (3DNow!+) ?extended 3DNow!
bit 29 (LM) ?AA-64, Long Mode(也就是AMD的X86-64指令集)
bit 28 ?保留
bits 27..25 ?保留
bit 24 (MMX+)
bit 24 (FXSR) ?Cyrix specific: extended MMX
AMD K7: FXSAVE/FXRSTOR, CR4.OSFXSR
bit 23 (MMX) ?MMX
bit 22 (MMX+) ?AMD specific: MMX-SSE and SSE-MEM
bit 21 ?保留
bit 20 (NX) ?EFER.NXE, P?E.NX, #PF(1xxxx)
bit 19 (MP) ?MP-capable #3
bit 18 ?保留
bit 17 (PSE36) ?4 MB PDE bits 16..13, CR4.PSE
bit 16 (FCMOV)
bit 16 (PAT) ?FCMOVcc/F(U)COMI(P) (implies FPU=1)
AMD K7: PAT MSR, PDE/PTE.PAT
bit 15 (CMOV) ?CMOVcc
bit 14 (MCA) ?MCG_*/MCn_* MSRs, CR4.MCE, #MC
bit 13 (PGE) ?PDE/PTE.G, CR4.PGE
bit 12 (MTRR) ?MTRR* MSRs
bit 11 (SEP) ?SYSCALL/SYSRET, EFER/STAR MSRs #1
bit 10 ?保留 #1
bit 9 (APIC) ?APIC #2
bit 8 (CX8) ?CMPXCHG8B
bit 7 (MCE) ?MCAR/MCTR MSRs, CR4.MCE, #MC
bit 6 (PAE) ?64bit PDPTE/PDE/PTEs, CR4.PAE
bit 5 (MSR) ?MSRs, RDMSR/WRMSR
bit 4 (TSC) ?TSC, RDTSC, CR4.TSD (doesn’t imply MSR=1)
bit 3 (PSE) ?PDE.PS, PDE/PTE.res, CR4.PSE, #PF(1xxxb)
bit 2 (DE) ?CR4.DE, DR7.RW=10b, #UD on MOV from/to DR4/5
bit 1 (VME) ?CR4.VME/PVI, EFLAGS.VIP/VIF, TSS32.IRB
bit 0 (FPU) ?FPU
说明 ?内容
#0 ?Intel 处理器不支持; 返回值EAX, EBX, ECX, 和 EDX都是0.
#1 ?AMD K6 处理器, model 6, uses 使用第十位指示SEP.
#2 ?如果APIC是无效的,那么APIC读到的是0.
#3 ?AMD CPUID=0662h的K7 处理器如果是具有多处理器能力的版本可能也报告时0
EAX= 8000_0002h, 8000_0003h, and 8000_0004h
输入 ?EAX=8000_0002h ?得到处理器名称的第一部分
EAX=8000_0003h ?得到处理器名称的第二部分
EAX=8000_0004h ?得到处理器名称的第三部分
输出 ?EAX
EBX
ECX
EDX ?处理器名称字符串#1
AMD K5 ?AMD-K5(tm) 处理器
AMD K6 ?AMD-K6tm w/ multimedia extensions
AMD K6-2 ?AMD-K6(tm) 3D 处理器
AMD-K6(tm)-2 处理器
AMD K6-III ?AMD-K6(tm) 3D+ 处理器
AMD-K6(tm)-III 处理器
AMD K6-2+ ?AMD-K6(tm)-III 处理器 (?)
AMD K6-III+ ?AMD-K6(tm)-III 处理器 (?)
AMD K7 ?AMD-K7(tm) 处理器 (model 1)
AMD Athlon(tm) 处理器 (model 2)
AMD Athlon(tm) 处理器 (models 3/4, 6/7, and 8 — programmable)
Centaur C2 #2 ?IDT WinChip 2
IDT WinChip 2-3D
VIA Cyrix III ?CYRIX III(tm) (?)
VIA Samuel (?)
VIA Ezra (?)
Intel P4 ?Intel(R) Pentium(R) 4 CPU xxxxMHz (right-justified, leading whitespaces)顺便说一句,Intel只有P4以上才支持。
Transmeta ?Transmeta(tm) Crusoe(tm) 处理器 TMxxxx
说明 ?内容
#1 ?是一个字符数组,以0H结尾.
#2 ?WinChip是否支持决定于是否支持3D Now!.
EAX= 8000_0005h
输入 ?EAX=8000_0005h ?得到L1缓存容量和入口数量 #1
输出 ?EAX ?4/2 MB L1 入口信息
EAX的位 ?描述
31..24 ?data TLB associativity (FFh=full)
23..16 ?data TLB entries
15..8 ?code TLB associativity (FFh=full)
7..0 ?code TLB entries
EBX ?4 KB L1入口信息
bits ?description
31..24 ?data TLB associativity (FFh=full)
23..16 ?data TLB entries
15..8 ?code TLB associativity (FFh=full)
7..0 ?code TLB entries
ECX ?data L1 信息描述
bits ?description
31..24 ?data L1 cache size in KBs
23..16 ?data L1 cache associativity (FFh=full)
15..8 ?data L1 cache lines per tag
7..0 ?data L1 cache line size in bytes
EDX ?code L1信息描述
bits ?description
31..24 ?code L1 cache size in KBs
23..16 ?code L1 cache associativity (FFh=full)
15..8 ?code L1 cache lines per tag
7..0 ?code L1 cache line size in bytes
说明 ?description
#1 ?Cyrix 处理器使用0000_0002h做类似的描述
EAX= 8000_0006h
输入 ?EAX=8000_0006h ?得到L1缓存容量和入口数量
输出 ?EAX ?4/2 MB L2 入口信息 #1
位 ?描述
31..28 ?data TLB associativity #2
27..16 ?data TLB entries
15..12 ?code TLB associativity #2
11..0 ?code TLB entries
EBX ?4 KB L2 入口信息
位 ?描述
31..28 ?data TLB associativity #1
27..16 ?data TLB entries
15..12 ?code TLB associativity #1
11..0 ?code TLB entries
ECX ?统一 L2 cache 信息 #32
bits ?description
31..16 #4 ?unified L2 cache size in KBs #3
15..12 #4 ?unified L2 cache associativity #1
11..8 #4 ?unified L2 cache lines per tag
7..0 ?unified L2 cache line size in bytes
说明 ?描述
#1 ?0000b=L2 off, 0001b=direct mapped, 0010b=2-way, 0100b=4-way, 0110b=8-way, 1000b=16-way, 1111b=full
#2 ?AMD K7 处理器 L2 cache 必须依赖于此信息.
#3 ?AMD PUID=0630h 的K7 处理器(Duron) 具有 64 KB二级缓存,但是却报告只有1KB.
#4 ?VIA Cyrix III CPUID=0670..068Fh (C5B/C5C)的处理器错误报告bits 31..24, 23..16, and 15..8.
EAX 8000_0007h
输入 ?EAX=8000_0007h ?电源管理信息(EPM)
输出 ?EDX ?EPM flags
位 ?说明
31..3 ?保留
2 (VID) ?voltage ID control supported
1 (FID) ?frequency ID control supported
0 ?temperature sensing diode supported
EAX= 8000_0008h
输入 ?EAX=8000_0008h ?得到地址大小信息
输出 ?EAX ?地址大小信息
位 ?说明
31..16 ?保留
15..8 ?virtual address bits
7..0 ?physical address bits
Transmeta EAX= 8086_0000h
输入 ?EAX=8086_0000h ?得到CPUID的最大支持和厂商字符串
输出 ?EAX=xxxx_xxxxh ?最大支持 EAX=l
EBX-EDX-ECX ?厂商字符串
TransmetaCPU ?Transmeta processor
Transmeta EAX= 8086_0001h
输入 ?EAX=8086_0001h ?得到处理器信息
输出 ?EAX=0000_0xxxh ?处理器信息
family ?The family is encoded in bits 11..8.
5 ?Transmeta Crusoe TM3x00 and TM5x00
model ?The model is encoded in bits 7..4.
Transmeta ?4 ?Crusoe TM3x00 and TM5x00
stepping ?The stepping is encoded in bits 3..0.
The stepping values are processor-specific.
EBX=aabb_ccddh ?hardware revision (a.b-c.d), if 2000_0000h: see EAX=l 8086_0002h register EAX instead
ECX=xxxx_xxxxh ?nominal core clock frequency (MHz)
EDX=xxxx_xxxxh ?feature flags ?description of indicated feature
bits 31..4 ?reserved
bit 3 (LRTI) ?LongRun Table Interface
bit 2 (???) ?unknown
bit 1 (LR) ?LongRun
bit 0 (BAD) ?recovery CMS active (due to a failed upgrade)
Transmeta EAX= 8086_0002h
输入 ?EAX=8086_0002h ?得到处理器信息
输出 ?EAX ?xxxx_xxxxh ?reserved or hardware revision (xxxxxxxxh)
see EAX=l 8086_0001h register EBX for details
EBX ?aabb_ccddh ?software revision, part 1/2 (a.b.c-d-x)
ECX ?xxxx_xxxxh ?software revision, part 2/2 (a.b.c-d-x)
Transmeta EAX=8086_0003h, 8086_0004h, 8086_0005h, and 8086_0006h
输入 ?EAX=8086_0003h ?得到信息字符串第一部分
EAX=8086_0004h ?得到信息字符串第一部分
EAX=8086_0005h ?得到信息字符串第一部分
EAX=8086_0006h ?得到信息字符串第一部分
输出 ?EAX-EBX-ECX-EDX ?信息字符串 #1
Transmeta ?20000805 23:30 official release 4.1.4#2 (例子)
说明 ?说明
#1 ?以00h为结尾的字符串.
Transmeta EAX= 8086_0007h
输入 ?EAX=8086_0007h ?得到处理器信息
输出 ?EAX ?xxxx_xxxxh ?当前时钟频率 (MHz)
EBX ?xxxx_xxxxh ?当前电压 (mV)
ECX ?xxxx_xxxxh ?当前占用率 (0..100%)
EDX ?xxxx_xxxxh ?当前的延迟 (fs)
神秘的功能 EAX= 8FFF_FFFEh
输入 ?EAX=8FFF_FFFEh ?未知 #1
输出 ?EAX ?0049_4544h ?DEI (according to one source: Divide Et Impera = Divide And Rule)
EBX ?0000_0000h ?保留
ECX ?0000_0000h ?保留
EDX ?0000_0000h ?保留
说明 ?说明
#1 ?这个方法仅仅被 AMD K6 支持.
神秘的功能EAX= 8FFF_FFFFh
输入 ?EAX=8FFF_FFFFh ?未知 #1
输出 ?EAX
EBX
ECX
EDX ?string ?NexGenerationAMD
说明 ?说明
#1 ?这个方法只被he AMD K6支持.
其他
输入 ?EAX=xxxx_xxxxh ?其他
输出 ?EAX=xxxx_xxxxh
EBX=xxxx_xxxxh
ECX=xxxx_xxxxh
EDX=xxxx_xxxxh ?不明确
代码如下:
type
TCPUIDResult = packed record
EAX: DWord;
EBX: DWord;
ECX: DWord;
EDX: DWord;
end;
TCPUInfo =packed record
Name: string[48];
Brand: Word;
APIC: DWORD;
Vendor: string[12];
Frequency: Real;
Family: integer;
Model: integer;
Stepping: integer;
EFamily: integer;
EModel: integer;
EStepping: integer;
MMX: Boolean;
MMXPlus: Boolean;
AMD3DNow: Boolean;
AMD3DNowPlus: Boolean;
SSE: Boolean;
SSE2: Boolean;
IA64: Boolean;
X86_64: Boolean;
end;

function CPUID(EAX: DWord): TCPUIDResult;
var
rEAX, rEBX, rECX, rEDX: DWord;
begin
asm
push EAX
push EBX
push ECX
push EDX
mov EAX,EAX
//******************************************************
//cpuid指令,因为Delphi的汇编编译器没有内置该指令,
//所以用该指令的机器语言代码$0F,$A2来实现
//******************************************************
db $0F,$A2
mov rEAX,EAX
mov rEBX,EBX
mov rECX,ECX
mov rEDX,EDX
pop EDX
pop ECX
pop EBX
pop EAX
end;
Result.EAX := rEAX;
Result.EBX := rEBX;
Result.ECX := rECX;
Result.EDX := rEDX;
end;

function GetCPUSpeed: Real;
const
timePeriod ? ? ? ?= 1000;
var
HighFreq, TestFreq, Count1, Count2: int64;
TimeStart ? ? ? ? : integer;
TimeStop ? ? ? ? ?: integer;
ElapsedTime ? ? ? : dword;
StartTicks ? ? ? ?: dword;
EndTicks ? ? ? ? ?: dword;
TotalTicks ? ? ? ?: dword;
begin
StartTicks := 0;
EndTicks := 0;
if QueryPerformanceFrequency(HighFreq) then
begin

TestFreq := HighFreq div 100;

QueryPerformanceCounter(Count1);
repeat
QueryPerformanceCounter(Count2);
until Count1 <> Count2;
asm
push ebx
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
db $0F,$A2 ? ? ? ? ? ? ? /// cpuid
db $0F,$31 ? ? ? ? ? ? ? /// rdtsc
mov StartTicks,eax
pop ebx
end;

repeat
QueryPerformanceCounter(Count1);
until Count1 – Count2 >= TestFreq;

asm
push ebx
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
db $0F,$A2 ? ? ? ? ? ? ? /// cpuid
db $0F,$31 ? ? ? ? ? ? ? /// rdtsc
mov EndTicks,eax
pop ebx
end;

ElapsedTime := MulDiv(Count1 – Count2, 1000000, HighFreq);
end
else
begin
timeBeginPeriod(1);
TimeStart := timeGetTime;

repeat
TimeStop := timeGetTime;
until TimeStop <> TimeStart;

asm
push ebx
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
db $0F,$A2 ? ? ? ? ? ? ? /// cpuid
db $0F,$31 ? ? ? ? ? ? ? /// rdtsc
mov StartTicks,eax
pop ebx
end;

repeat
TimeStart := timeGetTime;
until TimeStart – TimeStop >= timePeriod;

asm
push ebx
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
db $0F,$A2 ? ? ? ? ? ? ? /// cpuid
db $0F,$31 ? ? ? ? ? ? ? /// rdtsc
mov EndTicks,eax
pop ebx
end;
timeEndPeriod(1);

ElapsedTime := (TimeStart – TimeStop) * 1000;
end;
TotalTicks := EndTicks – StartTicks;
result := TotalTicks / ElapsedTime;
end;

function getCPUInfo: TCPUInfo;
type
TRegChar = array[0..3] of char;
var
lvCPUID ? ? ? ? ? : TCPUIDResult;
I ? ? ? ? ? ? ? ? : Integer;
begin
lvCPUID := CPUID(0);
Result.Vendor := TRegChar(lvCPUID.EBX) + TRegChar(lvCPUID.EDX) +
TRegChar(lvCPUID.ECX);
lvCPUID := CPUID(1);
Result.Frequency := GetCPUSpeed;
Result.Family := (lvCPUID.EAX and $F00) shr 8;
Result.Model := (lvCPUID.EAX and $78) shr 4;
Result.Stepping := (lvCPUID.EAX and $F);
Result.EFamily := (lvCPUID.EAX and $7800000) shr 20;
Result.EModel := (lvCPUID.EAX and $78000) shr 16;
Result.EStepping := (lvCPUID.EAX and $F);
Result.APIC := (lvCPUID.EBX and $1FE00000) shr 23;
Result.Brand := lvCPUID.EBX and $7F;
Result.MMX := (lvCPUID.EDX and $800000) = $800000;
Result.SSE := (lvCPUID.EDX and $2000000) = $2000000;
Result.SSE2 := (lvCPUID.EDX and $4000000) = $4000000;
Result.IA64 := (lvCPUID.EDX and $40000000) = $40000000;
lvCPUID := CPUID($80000001);
Result.MMXPlus := (lvCPUID.EDX and $800000) = $800000;
Result.AMD3DNow := (lvCPUID.EDX and $10000000) = $10000000;
Result.AMD3DNowPlus := (lvCPUID.EDX and $8000000) = $8000000;
Result.X86_64 := (lvCPUID.EDX and $40000000) = $40000000;
if (Result.Vendor = ‘GenuineIntel’) and ((Result.Family <> 15) or
(Result.EFamily <> 0)) then
Result.Name := Result.Vendor + ‘ Processor’
else
begin
Result.Name := ”;
for i := 2 to 4 do
begin
lvCPUID := CPUID($80000000 + i);
Result.Name := Result.Name +
TRegChar(lvCPUID.EAX) +
TRegChar(lvCPUID.EBX) +
TRegChar(lvCPUID.ECX) +
TRegChar(lvCPUID.EDX);
end;
Result.Name := Trim(Result.Name);
end;
end;

procedure TForm1.FormShow(Sender: TObject);

procedure WriteSupport(Edit: TEdit; Sup: Boolean);
begin
if Sup then
edit.Text := ‘支持’
else
edit.Text := ‘不支持’;
end;
var
CPU ? ? ? ? ? ? ? : TCPUInfo;
begin
CPU := getCPUInfo;
EditCPUName.Text := CPU.Name;
EditVendor.Text := CPU.Vendor;
EditF.Text := Inttostr(CPU.Family);
EditM.Text := Inttostr(CPU.Model);
EditStep.Text := Inttostr(CPU.Stepping);
EditFE.Text := Inttostr(CPU.EFamily);
EditME.Text := Inttostr(CPU.EModel);
EditStepE.Text := Inttostr(CPU.EStepping);
Edit33.Text := Inttostr(CPU.APIC);
EditBrand.Text := Inttostr(CPU.Brand);
EditSpeed.Text := FormatFloat(‘###.##’, CPU.Frequency);
WriteSupport(EditMMX, CPU.MMX);
WriteSupport(EditSSE, CPU.SSE);
WriteSupport(EditSSE2, CPU.SSE2);
WriteSupport(EditIA64, CPU.IA64);
WriteSupport(EditMMXp, CPU.MMXPlus);
WriteSupport(Edit3DNow, CPU.AMD3DNow);
WriteSupport(Edit3DNowp, CPU.AMD3DNowPlus);
WriteSupport(EditX86_64, CPU.X86_64);
end;

一个真正的CPU检测软件还要能够检测到缓存信息等等。大家可以参考上面表格所示的参数,在这些代码中作扩展。

CPU的资料好难找啊。Intel和AMD得还好一些,其他公司的简直是大海捞针。我尽力了,只能整理到这些了。

此条目发表在未分类分类目录。将固定链接加入收藏夹。