kenmark 发表于 2008-4-12 19:24:19

检测CPU信息的零零碎碎

有参考意义这是我收藏的一篇文,用的是ASM+DEPHI分析CPU信息,看到无心人在http://topic.csdn.net/u/20080403/15/80794e4a-24f3-402c-b510-9ba90f2d7006.html说想了解一下,里面有l2 cache检测的内容,分享一下,希望有用。实在不好意思,没有时间整理一下改写成C的,抱歉。:o
最近到整理了一份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
   GenuineIntelIntel 处理器
   UMC UMC UMCUMC 处理器
   AuthenticAMDAMD 处理器
   CyrixInsteadCyrix 处理器
   NexGenDrivenNexGen 处理器
   CentaurHaulsCentaur 处理器
   RiseRiseRiseRise Technology 处理器
   GenuineTMx86Transmeta 处理器
   Geode by NSCNational Semiconductor 处理器
说明描述
#1pre-B0 step Intel P5 处理器返回 EAX=0000_05xxh.
#2pre-B0 step Intel P5 处理器不能返回厂商字符串
EAX= 0000_0001h
输入EAX=0000_0001h得到处理器 type/family/model/stepping和 掩码标识
输出EAX=xxxx_xxxxh处理器 type/family/model/stepping
   extended familyextended family 是 bits 27..20.
   00hIntel P4
   01hIntel Itanium 2 (IA-64)
   extended modelextended model 是 bits 19..16.
   typetype是 bit 13 和 bit 12.
   11b保留
   10b第二块处理器
   01bOverdrive 处理器
   00b第一处理器
   familyfamily是bits 11..8.
   4most 80486s
AMD 5x86
Cyrix 5x86
   5Intel P5, P54C, P55C, P24T
NexGen Nx586
Cyrix M1
AMD K5, K6
Centaur C6, C2, C3
Rise mP6
Transmeta Crusoe TM3x00 and TM5x00
   6Intel P6, P2, P3
AMD K7
Cyrix M2, VIA Cyrix III
   7Intel Itanium (IA-64)
   F如果是这个值的话就看extended family
   modelmodel 是 bits 7..4.
   IntelF如果是这个值的话就看 extended model
   Intel 804860i80486DX-25/33
       1i80486DX-50
       2i80486SX
       3i80486DX2
       4i80486SL
       5i80486SX2
       7i80486DX2WB
       8i80486DX4
       9i80486DX4WB
   UMC 804861U5D
       2U5S
   AMD 80486380486DX2
       780486DX2WB
       880486DX4
       980486DX4WB
       E5x86
       F5x86WB
   Cyrix 5x8695x86
   Cyrix MediaGX4GX, GXm
   Intel P5-core0P5 A-step
       1P5
       2P54C
       3P24T Overdrive
       4P55C
       7P54C
       8P55C (0.25μm)
   NexGen Nx5860Nx586 or Nx586FPU (only later ones)
   Cyrix M126x86
   Cyrix M206x86MX
   VIA Cyrix III5Cyrix M2 core
       6WinChip C5A core
       7WinChip C5B core (if stepping = 0..7)
       7WinChip C5C core (if stepping = 8..F)
       8WinChip C5C-T core (if stepping = 0..7)
   AMD K50SSA5 (PR75, PR90, PR100)
       15k86 (PR120, PR133)
       25k86 (PR166)
       35k86 (PR200)
   AMD K66K6 (0.30 μm)
       7K6 (0.25 μm)
       8K6-2
       9K6-III
       DK6-2+ or K6-III+ (0.18 μm)
   Centaur4C6
       8C2
       9C3
   Rise0mP6 (0.25 μm)
       2mP6 (0.18 μm)
   Transmeta4Crusoe TM3x00 and TM5x00
   Intel P6-core0P6 A-step
       1P6
       3P2 (0.28 μm)
       5P2 (0.25 μm)
       6P2 with on-die L2 cache
       7P3 (0.25 μm)
       8P3 (0.18 μm)
with 256 KB on-die L2 cache
       AP3 (0.18 μm)
with 1 or 2 MB on-die L2 cache
       BP3 (0.13 μm)
with 256 or 512 KB on-die L2 cache
   AMD K71Athlon (0.25 μm)
       2Athlon (0.18 μm)
       3Duron (SF core)
       4Athlon (TB core)
       6Athlon (PM core)
       7Duron (MG core)
       8Athlon (TH core)
       AAthlon (Barton core)
   Intel P4-core0P4 (0.18 μm)
       1P4 (0.18 μm)
       2P4 (0.13 μm)
       3P4 (0.09 μm)
   steppingstepping 在 bits 3..0.
   Stepping描述的是处理器的细节.
EBX=aall_ccbbhbrand IDbrand ID是 7..0.
   00h不支持
   01h0.18 μm Intel Celeron
   02h0.18 μm Intel Pentium III
   03h0.18 μm Intel Pentium III Xeon
   03h0.13 μm Intel Celeron
   04h0.13 μm Intel Pentium III
   07h0.13 μm Intel Celeron mobile
   06h0.13 μm Intel Pentium III mobile
   0Ah0.18 μm Intel Celeron 4
   08h0.18 μm Intel Pentium 4
   09h0.13 μm Intel Pentium 4
   0Eh0.18 μm Intel Pentium 4 Xeon
   0Bh0.18 μm Intel Pentium 4 Xeon MP
   0Bh0.13 μm Intel Pentium 4 Xeon
   0Ch0.13 μm Intel Pentium 4 Xeon MP
   08h0.13 μm Intel Celeron 4 mobile
   0Eh0.13 μm Intel Pentium 4 mobile (production)
   0Fh0.13 μm Intel Pentium 4 mobile (samples)
   CLFLUSHCLFLUSH (8-byte)在 bits 15..8.
   CPU count逻辑处理器数量 bits 23..16.
   APIC ID默认(固定的)APIC ID是bits 31..24.
ECX=xxxx_xxxxhfeature 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是怎么想的).
#3APIC无效那么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配置描述
   值说明
   00hnull descriptor (=unused descriptor)
   01hcode TLB, 4K pages, 4 ways, 32 entries
   02hcode TLB, 4M pages, fully, 2 entries
   03hdata TLB, 4K pages, 4 ways, 64 entries
   04hdata TLB, 4M pages, 4 ways, 8 entries
   06hcode L1 cache, 8 KB, 4 ways, 32 byte lines
   08hcode L1 cache, 16 KB, 4 ways, 32 byte lines
   0Ahdata L1 cache, 8 KB, 2 ways, 32 byte lines
   0Chdata L1 cache, 16 KB, 4 ways, 32 byte lines
   10hdata L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
   15hcode L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
   1Ahcode and data L2 cache, 96 KB, 6 ways, 64 byte lines (IA-64)
   22hcode and data L3 cache, 512 KB, 4 ways (!), 64 byte lines, dual-sectored
   23hcode and data L3 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
   25hcode and data L3 cache, 2048 KB, 8 ways, 64 byte lines, dual-sectored
   29hcode and data L3 cache, 4096 KB, 8 ways, 64 byte lines, dual-sectored
   39hcode and data L2 cache, 128 KB, 4 ways, 64 byte lines, sectored
   3Bhcode and data L2 cache, 128 KB, 2 ways, 64 byte lines, sectored
   3Chcode and data L2 cache, 256 KB, 4 ways, 64 byte lines, sectored
   40hno integrated L2 cache (P6 core) or L3 cache (P4 core)
   41hcode and data L2 cache, 128 KB, 4 ways, 32 byte lines
   42hcode and data L2 cache, 256 KB, 4 ways, 32 byte lines
   43hcode and data L2 cache, 512 KB, 4 ways, 32 byte lines
   44hcode and data L2 cache, 1024 KB, 4 ways, 32 byte lines
   45hcode and data L2 cache, 2048 KB, 4 ways, 32 byte lines
   50hcode TLB, 4K/4M/2M pages, fully, 64 entries
   51hcode TLB, 4K/4M/2M pages, fully, 128 entries
   52hcode TLB, 4K/4M/2M pages, fully, 256 entries
   5Bhdata TLB, 4K/4M pages, fully, 64 entries
   5Chdata TLB, 4K/4M pages, fully, 128 entries
   5Dhdata TLB, 4K/4M pages, fully, 256 entries
   66hdata L1 cache, 8 KB, 4 ways, 64 byte lines, sectored
   67hdata L1 cache, 16 KB, 4 ways, 64 byte lines, sectored
   68hdata L1 cache, 32 KB, 4 ways, 64 byte lines, sectored
   70htrace L1 cache, 12 KμOPs, 8 ways
   71htrace L1 cache, 16 KμOPs, 8 ways
   72htrace L1 cache, 32 KμOPs, 8 ways
   77hcode L1 cache, 16 KB, 4 ways, 64 byte lines, sectored (IA-64)
   79hcode and data L2 cache, 128 KB, 8 ways, 64 byte lines, dual-sectored
   7Ahcode and data L2 cache, 256 KB, 8 ways, 64 byte lines, dual-sectored
   7Bhcode and data L2 cache, 512 KB, 8 ways, 64 byte lines, dual-sectored
   7Chcode and data L2 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
   7Ehcode and data L2 cache, 256 KB, 8 ways, 128 byte lines, sect. (IA-64)
   81hcode and data L2 cache, 128 KB, 8 ways, 32 byte lines
   82hcode and data L2 cache, 256 KB, 8 ways, 32 byte lines
   83hcode and data L2 cache, 512 KB, 8 ways, 32 byte lines
   84hcode and data L2 cache, 1024 KB, 8 ways, 32 byte lines
   85hcode and data L2 cache, 2048 KB, 8 ways, 32 byte lines
   88hcode and data L3 cache, 2048 KB, 4 ways, 64 byte lines (IA-64)
   89hcode and data L3 cache, 4096 KB, 4 ways, 64 byte lines (IA-64)
   8Ahcode and data L3 cache, 8192 KB, 4 ways, 64 byte lines (IA-64)
   8Dhcode and data L3 cache, 3096 KB, 12 ways, 128 byte lines (IA-64)
   90hcode TLB, 4K...256M pages, fully, 64 entries (IA-64)
   96hdata L1 TLB, 4K...256M pages, fully, 32 entries (IA-64)
   9Bhdata L2 TLB, 4K...256M pages, fully, 96 entries (IA-64)
   值描述
   70hCyrix specific: code and data TLB, 4K pages, 4 ways, 32 entries
   74hCyrix specific: ???
   77hCyrix specific: ???
   80hCyrix specific: code and data L1 cache, 16 KB, 4 ways, 16 byte lines
   82hCyrix specific: ???
   84hCyrix specific: ???
   值描述
   others保留
举个例子有一块 P6EAX=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厂家的名称字符串
   AuthenticAMDAMD
   保留Cyrix
   保留Centaur
   保留Intel
   TransmetaCPUTransmeta
   保留National Semiconductor
extended EAX= 8000_0001h
输入EAX=8000_0001h得到处理器 family/model/stepping and features flags #0
输出EAX=0000_0xxxh处理器 family/model/stepping
   familyFamily是 bits 11..8.
       5AMD K5
Centaur C2
Transmeta Crusoe TM3x00 and TM5x00
       6AMD K6
VIA Cyrix III
       7AMD K7
   modelmodel 是bits 7..4.
   AMD K515k86 (PR120 or PR133)
       25k86 (PR166)
       35k86 (PR200)
   AMD K66K6 (0.30 μm)
       7K6 (0.25 μm)
       8K6-2
       9K6-III
       DK6-2+ or K6-III+ (0.18 μm)
   AMD K71Athlon (0.25 μm)
       2Athlon (0.18 μm)
       3Duron (SF core)
       4Athlon (TB core)
       6Athlon (PM core)
       7Duron (MG core)
       8Athlon (TH core)
       AAthlon (Barton core)
   Centaur8C2
       9C3
   VIA Cyrix III5Cyrix M2 core
       6WinChip C5A core
       7WinChip C5B core (if stepping = 0..7)
       7WinChip C5C core (if stepping = 8..F)
       8WinChip C5C-T core (if stepping = 0..7)
   Transmeta4Crusoe TM3x00 and TM5x00
   steppingstepping是bits 3..0.
   Stepping的值是处理器的细节.
EDX=xxxx_xxxxhfeature flagsdescription 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
说明内容
#0Intel 处理器不支持; 返回值EAX, EBX, ECX, 和 EDX都是0.
#1AMD K6 处理器, model 6, uses 使用第十位指示SEP.
#2如果APIC是无效的,那么APIC读到的是0.
#3AMD 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 K5AMD-K5(tm) 处理器
   AMD K6AMD-K6tm w/ multimedia extensions
   AMD K6-2AMD-K6(tm) 3D 处理器
AMD-K6(tm)-2 处理器
   AMD K6-IIIAMD-K6(tm) 3D+ 处理器
AMD-K6(tm)-III 处理器
   AMD K6-2+AMD-K6(tm)-III 处理器 (?)
   AMD K6-III+AMD-K6(tm)-III 处理器 (?)
   AMD K7AMD-K7(tm) 处理器 (model 1)
AMD Athlon(tm) 处理器 (model 2)
AMD Athlon(tm) 处理器 (models 3/4, 6/7, and 8 -- programmable)
   Centaur C2 #2IDT WinChip 2
IDT WinChip 2-3D
   VIA Cyrix IIICYRIX III(tm) (?)
VIA Samuel (?)
VIA Ezra (?)
   Intel P4Intel(R) Pentium(R) 4 CPU xxxxMHz (right-justified, leading whitespaces)顺便说一句,Intel只有P4以上才支持。
   TransmetaTransmeta(tm) Crusoe(tm) 处理器 TMxxxx
说明内容
#1是一个字符数组,以0H结尾.
#2WinChip是否支持决定于是否支持3D Now!.
EAX= 8000_0005h
输入EAX=8000_0005h得到L1缓存容量和入口数量 #1
输出EAX4/2 MB L1 入口信息
   EAX的位描述
   31..24data TLB associativity (FFh=full)
   23..16data TLB entries
   15..8code TLB associativity (FFh=full)
   7..0code TLB entries
EBX4 KB L1入口信息
   bitsdescription
   31..24data TLB associativity (FFh=full)
   23..16data TLB entries
   15..8code TLB associativity (FFh=full)
   7..0code TLB entries
ECXdata L1 信息描述
   bitsdescription
   31..24data L1 cache size in KBs
   23..16data L1 cache associativity (FFh=full)
   15..8data L1 cache lines per tag
   7..0data L1 cache line size in bytes
EDXcode L1信息描述
   bitsdescription
   31..24code L1 cache size in KBs
   23..16code L1 cache associativity (FFh=full)
   15..8code L1 cache lines per tag
   7..0code L1 cache line size in bytes
说明description
#1Cyrix 处理器使用0000_0002h做类似的描述
EAX= 8000_0006h
输入EAX=8000_0006h得到L1缓存容量和入口数量
输出EAX4/2 MB L2 入口信息 #1
   位描述
   31..28data TLB associativity #2
   27..16data TLB entries
   15..12code TLB associativity #2
   11..0code TLB entries
EBX4 KB L2 入口信息
   位描述
   31..28data TLB associativity #1
   27..16data TLB entries
   15..12code TLB associativity #1
   11..0code TLB entries
ECX统一 L2 cache 信息 #32
   bitsdescription
   31..16 #4unified L2 cache size in KBs #3
   15..12 #4unified L2 cache associativity #1
   11..8 #4unified L2 cache lines per tag
   7..0unified L2 cache line size in bytes

kenmark 发表于 2008-4-12 19:24:57

说明描述
#10000b=L2 off, 0001b=direct mapped, 0010b=2-way, 0100b=4-way, 0110b=8-way, 1000b=16-way, 1111b=full
#2AMD K7 处理器 L2 cache 必须依赖于此信息.
#3AMD PUID=0630h 的K7 处理器(Duron) 具有 64 KB二级缓存,但是却报告只有1KB.
#4VIA Cyrix III CPUID=0670..068Fh (C5B/C5C)的处理器错误报告bits 31..24, 23..16, and 15..8.
EAX 8000_0007h
输入EAX=8000_0007h电源管理信息(EPM)
输出EDXEPM flags
   位说明
   31..3保留
   2 (VID)voltage ID control supported
   1 (FID)frequency ID control supported
   0temperature sensing diode supported
EAX= 8000_0008h
输入EAX=8000_0008h得到地址大小信息
输出EAX地址大小信息
   位说明
   31..16保留
   15..8virtual address bits
   7..0physical address bits
Transmeta EAX= 8086_0000h
输入EAX=8086_0000h得到CPUID的最大支持和厂商字符串
输出EAX=xxxx_xxxxh最大支持 EAX=l
EBX-EDX-ECX厂商字符串
   TransmetaCPUTransmeta processor
Transmeta EAX= 8086_0001h
输入EAX=8086_0001h得到处理器信息
输出EAX=0000_0xxxh处理器信息
   familyThe family is encoded in bits 11..8.
       5Transmeta Crusoe TM3x00 and TM5x00
   modelThe model is encoded in bits 7..4.
   Transmeta4Crusoe TM3x00 and TM5x00
   steppingThe stepping is encoded in bits 3..0.
   The stepping values are processor-specific.
EBX=aabb_ccddhhardware revision (a.b-c.d), if 2000_0000h: see EAX=l 8086_0002h register EAX instead
ECX=xxxx_xxxxhnominal core clock frequency (MHz)
EDX=xxxx_xxxxhfeature flagsdescription of indicated feature
   bits 31..4reserved
   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得到处理器信息
输出EAXxxxx_xxxxhreserved or hardware revision (xxxxxxxxh)
see EAX=l 8086_0001h register EBX for details
EBXaabb_ccddhsoftware revision, part 1/2 (a.b.c-d-x)
ECXxxxx_xxxxhsoftware 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
   Transmeta20000805 23:30 official release 4.1.4#2 (例子)
说明说明
#1以00h为结尾的字符串.
Transmeta EAX= 8086_0007h
输入EAX=8086_0007h得到处理器信息
输出EAXxxxx_xxxxh当前时钟频率 (MHz)
EBXxxxx_xxxxh当前电压 (mV)
ECXxxxx_xxxxh当前占用率 (0..100%)
EDXxxxx_xxxxh当前的延迟 (fs)
神秘的功能 EAX= 8FFF_FFFEh
输入EAX=8FFF_FFFEh未知 #1
输出EAX0049_4544hDEI (according to one source: Divide Et Impera = Divide And Rule)
EBX0000_0000h保留
ECX0000_0000h保留
EDX0000_0000h保留
说明说明
#1这个方法仅仅被 AMD K6 支持.
神秘的功能EAX= 8FFF_FFFFh
输入EAX=8FFF_FFFFh未知 #1
输出EAX
EBX
ECX
EDXstringNexGenerationAMD
说明说明
#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;
   Brand: Word;
   APIC: DWORD;
   Vendor: string;
   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 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得还好一些,其他公司的简直是大海捞针。我尽力了,只能整理到这些了。

kenmark 发表于 2008-4-12 19:33:22

再发一个CSDN上的代码,VC+ASM的,稍微看了一下代码,还可以,用一下可以获取L2 cache等基本信息,一同分享一下

[ 本帖最后由 kenmark 于 2008-4-12 19:54 编辑 ]

gxqcn 发表于 2008-4-12 19:37:03

谢谢你提供的参考资料。编程时最好是参考厂商提供的技术文档写代码。

注意:上面帖子文本中含有美元符,必须在其前面添加转义符“\”,否则会被误解析成数学公式:(
我已帮你重新编辑过了。

kenmark 发表于 2008-4-12 19:39:21

多谢老大

无心人 发表于 2008-4-12 20:24:38

我手里的资料比你的还详细呢
可是这么多CPU信息
这么多种类的CPU
如何辨认出L2Cache项啊
貌似很多CPU的L2Cache信息都是在不同位置保存的

无心人 发表于 2008-4-12 20:31:16

还是先谢谢你的分享
C代码和Delphi俺都需要
:lol

如果不是Delphi不流行
他做数学计算可比C要稳定哦

大概知道如何做了
不过有点繁琐

kenmark 发表于 2008-4-12 20:39:43

的确很麻烦,所以最好做一个结构体,以备查
这类资料的确很多大多是manual的翻译,数量庞大以至于没人愿意整理,老实说整理了也没多大意义,呵呵
页: [1]
查看完整版本: 检测CPU信息的零零碎碎