zoukankan      html  css  js  c++  java
  • CPUID

    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 有效,否则无效
           

     pushfd                  ;使延伸旗标推入堆叠
            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 保留

     待续 。。。


  • 相关阅读:
    选择正确的API从SQL Server获取XML数据
    XmlTextWriter学习笔记[转]
    简单的在线RSS阅读器[转]
    如何从客户端 JavaScript 调用 .NET Web 服务使用 InternetExplorer 和 MSXML
    用xmlhttp将html的数据打包成multipart/formdata格式,实现异步上传文件功能[转]
    ASP.Net中MD5加密16位32位
    第一个XMLHTTP测试成功![原创]
    php目录操作函数
    原创JS幻灯片效果,超少代码
    PHP MVC设想,MVC框架构思(一)
  • 原文地址:https://www.cnblogs.com/gredswsh/p/wasm_cpu_id.html
Copyright © 2011-2022 走看看