关于CPU序列号的问题,以及如何获取×64下CPU的ProcessorID

日常 专栏收录该内容
15 篇文章 0 订阅

前几天经过查资料,得到网络上获取CPU序列号的方法是错误的,首先我找到了一篇论文,这篇论文里面是这么说的:

这篇论文是错误的。这篇是错误的这篇是错误的!!!!!!!!!

2、CPU序列号

CPU序列号是一个建立在处理器内部的、唯一的、不能被修改的编号。它由96位数字组成。高32位是CPUID,用来识别CPU类型。低64位每个处理器都不同,唯一地代表了该处理器。CPU号可以用来识别每一个处理器。为了适应这一新特征,Intel在处理中增加了两条指令(“读取”和“禁止”)和一个寄存器位。读取指令扩展了CPUID读取指令。当执行读取指令时可以得到96位的处理器序列号。禁止指令可以禁止对处理器序列号的读取。为了配合CPU序列号的读取和禁止,设置了MSR位。当MSR位为“0”时可以读取CPU序列号;当MSR为“1”时只能读取高32位(即CPUID)而低64位全为零。

2、实现过程

(1)CPU号的读取

硬盘的序列号只能采用对硬盘控制器直接操作的方式进行读取,也就是说只能采用CPU的I/O指令操作硬盘控制器,对于CPU号的读取采用了在DELPHI嵌入汇编的方法读取。

其读取方法如下:MOVEAX,01H

如果返回的EDX中,低18位为1,那么这个CPU就是支持序列号的。此时EAX就是序列号的高32位。这32位对同一型号的CPU是一样的。再执行:

MOVEAX,03H

此时的EDX:ECX就是序列号的第64位。

这就是这篇论文所说的关于CPU序列号的问题,当时我被这个问题困扰了好久,因为在我的机器上他所谓的EDX:ECX是获取不到的,而且网络上也没有关于MSR这个寄存器 的说明,因此,我怀疑网上的这篇论文可能是错误的。

于是机缘巧合下我去查了维基百科。

https://en.wikipedia.org/wiki/CPUID

有兴趣的人可以自己去研究下。这里我只说重点,当__cpuid()这个命令输入的是3的时候按商编的文章我们可以得到低64位序列号,但是维基里面说了。

EAX=3: Processor Serial Number[edit]

This returns the processor's serial number. The processor serial number was introduced on Intel Pentium III, but due to privacy concerns, this feature is no longer implemented on later models (PSN feature bit is always cleared). Transmeta's Efficeon and Crusoe processors also provide this feature. AMD CPUs however, do not implement this feature in any CPU models.

For Intel Pentium III CPUs, the serial number is returned in EDX:ECX registers. For Transmeta Efficeon CPUs, it is returned in EBX:EAX registers. And for Transmeta Crusoe CPUs, it is returned in EBX register only.

Note that the processor serial number feature must be enabled in the BIOS setting in order to function.

他说,这个是返回的处理器的序列号,但是这个序列号早在奔腾3就被废弃了,主要是为了保护个人的隐私。而且这个值之后的处理器也不再使用,所以。你们那些博客里面说能够获取到的是在逗我么,不考虑正确性就瞎转。关于那篇文章我后来查了下根源,发现是某个杂志上面的。但是这个东西真的是错误的,这个是获取不到的。我们可以获取到的是这个值:(相对于这种杂志我更相信维基)

C:\Users\Admin>wmic CPU get ProcessorID
ProcessorId
BFEBFBFF000206A7

****************************************我是萌萌的分割线********************************************************************

说了这么多这些,我来说说如何在64位系统下获得CPUID

因为微软在64位系统下不再支持内联汇编这么程序的编写方式,所以我们就不能使用像32位程序的内联汇编来获取CPUID。如何获取,也是在网上搜索到的一种方法是不能用内联汇编,那就用外部调用,好吧外部编写汇编程序,反真我是不会。这里就不说了。

另一种方法:人性化的微软为我们提供了两个函数:

我们来看看MSDN:

__cpuid, __cpuidex

Generates the cpuid instruction that is available on x86 and x64. This instruction queries the processor for information about the supported features and CPU type.

这个cpuid函数可以用于获取处理器的信息(关于被支持的特征和处理器的种类)。

void __cpuid(
   int CPUInfo[4],
   int InfoType
);

void __cpuidex(
   int CPUInfo[4],
   int InfoType,
   int ECXValue
);

Parameters
[out]  CPUInfo

An array of four integers that contains the gathered information about supported features and the CPU.

[in]  InfoType

A code that indicates what information this instruction retrieves.

[in]  ECXValue

The value of the ECX register before this intrinsic generates the cpuid instruction.

Intrinsic

Architecture

__cpuid

x86, x64

__cpuidex

x86, x64

Header file  <intrin.h>

我们要获取ProcessorID的值就像在CMD输入命令一样的值,例子如下:(用法跟内联汇编一样的参数,但是比汇编简单多了32 64 都支持!!!

#include<iostream>
#include<intrin.h>
using namespace std;

int main()
{
INT32 deBuf[4];

__cpuidex(deBuf,01,0);
printf(%.8x%.8x,deBuf[0],deBuf[3]);
return 0;
}


  • 6
    点赞
  • 4
    评论
  • 7
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值