zoukankan      html  css  js  c++  java
  • Delphi编程 使用CPUID指令获取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/AMD K8
         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 5x86
    Cyrix 5x86
         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  5x86
           F  5x86WB
         Cyrix 5x86  9  5x86
         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  6x86
         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)
                                    AMD K8     5         Opteron DP (0.13 µm)
         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是 bits 27..20.
                            00h AMD K8
       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)
                                     AMD K8    5         Opteron DP (0.13 µm)
         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)
    AMD K8 programmable via MSRs C001_0030h..C001_0035h, default is 48x 00h
       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得还好一些,其他公司的简直是大海捞针。我尽力了,只能整理到这些了。  
  • 相关阅读:
    NOIP2015 斗地主
    BZOJ 2120: 数颜色
    BZOJ 1014: [JSOI2008]火星人prefix
    BZOJ 4665: 小w的喜糖
    BZOJ 3665: maths
    BZOJ 3270: 博物馆
    BZOJ 1419: Red is good
    【转】二分图的最大匹配
    POJ 3026 Borg Maze(Prim+BFS建邻接矩阵)
    POJ 2485 Highway(Prim+邻接矩阵)
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/992873.html
Copyright © 2011-2022 走看看