用cpuid指令读取CPU信息

#include

int main()

{

unsigned int eflags1, eflags2 = 0;

unsigned int eax = 0;

unsigned int ebx,ecx,edx;

/**

* 测试CPU是否支持CPUID指令。

* eflags寄存器的第21位,如果程序可以清楚/设置它,则说明CPU支持CPUID指令。否则不支持

*/

/* 先取eflags */

asm volatile ("pushf\n\t"

"popl %%eax"

: "=a"(eflags1)

:

: "memory"

);

printf("original eflags is %p\n", eflags1);

/* 把eflags的第21位取反,写回寄存器中 */

asm volatile ("pushl %0\n\t"

"popf"

:

: "g"(eflags1 & ~( eflags1 & (1<<21) ) )

);

/* 检查一下现在的eflags,确认第21位和最初的值相反 */

asm volatile ("pushf\n\t"

"popl %%eax"

: "=a"(eflags2)

:

: "memory"

);

printf("modified eflags is %p\n", eflags2);

/* 把原来的eflags值设置回去 */

asm volatile ("pushl %0\n\t"

"popf"

:

: "g"(eflags1)

);

/**

* FIXME: Intel文档并没有说,如果不支持CPUID的话,clear/set eflags的第21位会有什么错误。

* 它只说,在不支持CPUID指令的CPU上,如80386,执行CPUID会产生invalid opcode错误

*

* 所以,在这里我们不处理 读/写 eflags 第21比特失败的情形

*/

/**

*  eax == 1,则在eax中返回Family/Model/Stepping等信息

*  [0:3]    stepping

*  [4:7]    model

*  [8:11]    family

*  [12:13]    processor type

*  [16:19]    extended model ID

*  [20:27]    extended family ID

*/

asm volatile ("cpuid"

: "=a"(eax)

: "0"(1)

);

// printf("eax is %p\n", eax);

printf("Extended Family\t: %d\n", (0xff00000 & eax) >> 20);

printf("Extended Model\t: %d\n", (0xf0000 & eax) >> 16);

printf("Processor type\t: %d\n", (0x3000 & eax) >> 12);

printf("Family\t\t: %d\n", (0xf00 & eax) >> 8);

printf("Model\t\t: %d\n", (0xf0 & eax) >> 4);

printf("Stepping:\t: %d\n", (0xf & eax));

printf("\n");

/**

* eax == 0x800000000

* 如果CPU支持Brand String,则在EAX中返 >= 0x80000004的值。

*/

asm volatile ("cpuid"

: "=a"(eax)

: "0"(0x80000000)

);

printf("Is CPU support Brand String? %s\n", eax >= 0x80000004? "yes":"no");

printf("\n");

/**

* 如果支持Brand String,则EAX从0x80000002到0x80000004,每次增1,CPUID指令返回:

* EAX    : Processor Brand String

* EBX    : Processor Brand String Continued

* ECX    : Processor Brand String Continued

* EDX    : Processor Brand String Continued

*/

if(eax >= 0x80000004) {

unsigned int brands[4]; //每次的eax、ebx、ecx、edx

unsigned int i;

printf("Brand String\t: ");

for (i = 0x80000002; i <= 0x80000004; i++) {

asm volatile ("cpuid"

: "=a"(brands[0]), "=b"(brands[1]), "=c"(brands[2]), "=d"(brands[3])

: "0" (i)

);

printf("%s", (char *)brands);

}

//FIXME: 打出来的字符串是:In^Htel(R) Pentium(R^H) D CPU 2.80GHz

//其中^H是个不可见字符,会把它前一个吃掉

printf("\n");

}

/**

* eax == 0

* eax    : cpuid指令允许的最大eax输入值

* ebx    : "Genu"

* ecx    : "ntel"

* edx    : "inel"

*/

asm volatile ("cpuid"

: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)

: "0"(0) );

printf("Maximum CPUID Input EAX : %p\n", eax);

char string[128];

snprintf(string, 5, "%s", (char *)&ebx);

snprintf(string + 4, 5, "%s", (char *)&edx);

snprintf(string + 8, 5, "%s", (char *)&ecx);

printf("Vendor\t\t: %s\n", string);

printf("\n");

/**

* eax == 1,

* edx的第18比特为1,则CPU支持serial number

*         为0,则不支持,或者被disabled

* 序列号有96位,其中最高32位即是eax的输出值。应当把它保存下来,然后

* 再设置eax==3, 取剩下的64位

*/

asm volatile ("cpuid"

: "=a"(eax), "=d"(edx)

: "a"(1)

);

if ( edx & (1 << 18) ) {

/* serial number supported */

/* edx输出中间32位的序列号,ecx输出最低32位的序列号 */

asm volatile ("cpuid"

: "=c"(ecx), "=d"(edx)

: "a"(3)

);

printf("Serial Number\t : %x-%x-%x-%x-%x-%x\n",

eax >> 16, eax << 16, edx >> 16, edx << 16, ecx >> 16, ecx << 16);

} else

printf("Serial Number not supported.\n");

printf("\n");

/**

* eax == 80000006h,返回L2 Cache的信息

*

* ecx[31:16]    : L2 Cache size, in Kbytes

* ecx[15:12]    : L2 Cache Associativity

*           00h disabled

*           01h direct mapped

*           02h 2-Way

*           04h 4-Way

*           06h 8-Way

*           08h 16-Way

*           0Fh Fully associative

* ecx[7:0]    : L2 Cache Line size in bytes

*/

asm volatile ("cpuid"

: "=c"(ecx)

: "a"(0x80000006)

);

printf("L2 Cache Size\t : %dKbytes\n", ( ecx >> 16 ) );

printf("L2 Cache Line Size\t : %dbytes\n", (ecx & 0xff));

printf("L2 Cache Associativity\t : ");

switch ( (ecx & 0xf000) >> 12 )

{

case 0x00:

printf("%s\n", "disabled");

break;

case 0x01:

printf("%s\n", "direct mapped");

break;

case 0x02:

printf("%s\n", "2-Way");

break;

case 0x04:

printf("%s\n", "4-Way");

break;

case 0x06:

printf("%s\n", "8-Way");

break;

case 0x08:

printf("%s\n", "16-Way");

break;

case 0x0f:

printf("Fully associative");

break;

default:

printf("No such entry...\n");

}

printf("\n");

/**

* Input : eax == 4 && ecx == 0

*

* (eax[31:26] + 1) 是该物理处理器package上实现的core CPUs数目

*/

asm volatile ("cpuid"

: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)

: "0"(4), "2"(0)

);

printf("Number of Cores on this physical package\t : %d\n", (eax >> 27) + 1 );

printf("\n");

/**

* Input : eax == 1,则edx返回feature flag

*

*/

return 0;

}

java cpuid_用cpuid指令读取CPU信息相关推荐

  1. 通过CPUID指令读取处理器信息

    一.CPUID简介 CPUID操作码是一个面向x86架构的处理器补充指令,它的名称派生自CPU识别,作用是允许软件通过CPUID指令读取处理器的详细信息. 二.CPUID基本原理 CPUID有很多fu ...

  2. linux cpuid指令,通过CPUID指令获取CPU信息

    1.简介 在计算机领域中需要用到CPU信息的地方有很多.比如,在可信计算中,需要收集终端的软硬件的完整性信息,其中就包含CPU的信息:再比如,一些加密软件需要绑定CPU的某些信息,去生成加密密钥.本文 ...

  3. Intel x86_64使用cpuid指令获取CPU信息

    文章目录 前言 一.cpuid指令简介 1.1 cpuid指令功能 1.2 cpuid指令代码 二.获取处理器信息 2.1 输入参数为0H 2.2 输入参数为01H 2.3 输入参数为0x800000 ...

  4. Delphi编程 -- 使用CPUID指令获取CPU信息(转自大富翁)

    最近到整理了一份CPU的信息,应该算是比较全面的吧. 几乎现在所有的X86 CPU都内置了CPUID指令以辨别真伪,一些CPU厂商例如AMD,VIA等还内置了更加丰富的扩展CPUID指令,用着更方便了 ...

  5. 通过读取/proc/cpuinfo获取CPU信息

    1.简介 上一篇介绍了如何通过cpuid指令获取CPU信息,本文主要介绍如何通过读取/proc/cpuinfo文件获取CPU信息.本文从"什么是/proc文件系统","如 ...

  6. CPUID获取本机CPU信息

    CPUID获取本机CPU信息 目录 问题 分析 代码 运行结果 问题 请使用Visual Studio编写一个控制台程序,功能如下: 一.使用命令CPUInfo.exe -C读取本机CPU信息,并存储 ...

  7. Intel CPU的CPUID指令

    Intel有一个超过100页的文档,专门介绍cpuid这条指令,可见这条指令涉及内容的丰富. 记得去年的时候,曾经有个"英布之剑"问过我这条指令,当时并没有给出一个满意的回答,现在 ...

  8. java 线程 cpu_java程序中线程cpu使用率计算

    最近确实遇到题目上的刚需,也是花了一段时间来思考这个问题. cpu使用率如何计算 计算使用率在上学那会就经常算,不过往往计算的是整个程序执行的时间段,现在突然要实时计算还真有点无奈,时间段如何选择是个 ...

  9. 【汇编优化】之CPUID获取x86处理器信息

    ###1.CPUID - CPU 标识 操作码 指令 说明 OF A2 CPUID 按照最初输入 EAX 寄存器的值,将处理器标识与功能信息返回给 EAX.EBX.ECX 及 EDX 寄存器. 说明 ...

最新文章

  1. Linux下*.tar.bz2等文件如何解压--转
  2. C# 读取计算机CPU,HDD信息
  3. 给程序员的10条建议
  4. 数据结构之图的应用:有向无环图
  5. ElasticSearch中doc values和fielddata
  6. 【Flink】解决Flink在测试环境无法保存checkpoint问题
  7. flink source 同步_Flink面试题
  8. matlab2012 powerlib,matlab没有powerlib2
  9. .NET框架怎样解决DLL Hell问题?
  10. stella forum 知识库---一些错误的修补
  11. linux下怎么解压tar.gz,linux下怎么解压.tar.gz .tar.bz2命令
  12. 数据库系统原理与应用教程(014)—— 关系数据库练习题(一)
  13. 为什么现在一些年轻人放弃缴纳社保?
  14. 原生JS实现任意数据的动态表格
  15. 毕业设计:基于java的小区物业信息管理系统的设计与实现(1)
  16. 一键清除苹果锁屏密码_苹果手机锁屏密码突然不正确了?不要慌!也先不要着急刷机!!!尝试一下以下方式!...
  17. PHP 获取浏览器以及版本号
  18. 大学生图书借阅分析【上篇】
  19. Nature综述 | 肠道菌群在心脏代谢性疾病预防与治疗中的应用潜力
  20. 网络结构及mac和phy介绍

热门文章

  1. 6种实现前端下载图片的方法汇总
  2. 存储器管理之分页存储管理
  3. 股票记录-2017-8-17晚上总结
  4. 基于 Tile PPU 的 Unity Camera Size 计算公式
  5. [架构之路-30]:目标系统 - 系统软件 - Linux OS根文件系统rootfs的概念、组成、制作以及用busybox制作根文件系统
  6. 自主研发零兵兵棋对抗+推演+决策系统开发功能设计
  7. sqlserver性能调优入门篇
  8. 五、基于github+阿里云容器镜像服务进行docker部署
  9. Phonopy 内网 安装 天河二号
  10. matlab商品市场占有率问题,市场占有率与集中度分析–Excel模板