CPUID 为英特尔处理器返回“GenuntellineI”

Posted

技术标签:

【中文标题】CPUID 为英特尔处理器返回“GenuntellineI”【英文标题】:CPUID returning "GenuntellineI" for Intel Processor 【发布时间】:2015-07-21 11:49:11 【问题描述】:

我正在尝试获取一个打印出 CPU 名称/供应商的函数,但是当我尝试它时,我最终得到了“GenuntellineI”。

函数如下:

void PrintProcessingDeviceType()

    uint32_t regs[4];

    #ifdef _WIN32
    __cpuid((int*)regs, 0);
    #else
    asm volatile ("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) : "a" (0), "c" (0));
    #endif

    std::cout << std::string((const char*)&regs, 16) << std::endl;

两个路径(定义了 _WIN32 和未定义的路径)都会导致发生此错误。这是 CPUID 不正确的问题,是我做错了什么,还是什么?

【问题讨论】:

尝试运行 msdn 示例,看看错误是否仍然存在:msdn.microsoft.com/en-us/library/… @BetaCarotin 当我尝试编译 MSDN 示例时,我收到错误“__cpuidex 未在此范围内声明”。所以这是不可能的。 【参考方案1】:

为什么你会期待不同的东西? 如果某条指令的行为与您的预期不同,请查阅英特尔手册。

【讨论】:

【参考方案2】:

这似乎是 CPUID 函数的一个怪癖,有关详细信息,请参阅http://www.microbe.cz/docs/CPUID.pdf(第 2.1.1 节)。 (对于 quirk 的松散定义;它没有被标记为这样,但很容易被忽略。)

它返回寄存器 EBX 中的前 4 个字节,EDX 中的后 4 个字节和 ECX 中的最后一个字节。请注意两点:首先,EAX (regs[0]) 的结果不包含模型名称的任何字符,因此您应该只打印它以 regs[1] 开头。其次,最后两个寄存器的顺序是“颠倒的”。如果您交换数组的各个条目,您应该得到正确的字符串(即regs[2]regs[3])。

【讨论】:

有趣的是,虽然交换 regs[2]regs[3] 确实可以通过使控制台上唯一可见的文本打印为“GenuineIntel”(除了一些奇怪的间距),删除 regs[0] 或做任何其他修改都会导致字符串发生巨大变化,有时甚至会缩小(或者从控制台窗口中显示)。 奇怪。但是,我现在无法尝试,并想分享我在 PDF 中找到的内容 :-) 如果您发现出现奇怪行为的原因,请发布!【参考方案3】:

您可以将 CPUID 指令视为一个函数,该函数将通过 EAX 寄存器传递的参数值作为参数值,即。 CPUID 返回的内容完全取决于执行 CPUID 之前 EAX 中的内容。

在您的情况下,在执行 CPUID 之前,您的 EAX 等于 0。这样 CPUID 会返回您机器上的基本处理器信息 GenuinIntel。 AMD 处理器在相同情况下会返回AuthenticAMD

由于每个处理器都略有不同,CPUID 的行为取决于您的 CPU,因此在获取基本 CPU 信息后,您必须使用 CPUID 的特定参数来了解有关 CPU 功能等的更多信息。为此,您需要描述 CPUID 的特定 CPU 文档。

anderas 已经为您提供了 Intel 的 CPUID pdf。在这里你可以得到 AMD:

http://support.amd.com/TechDocs/25481.pdf#search=cpuid

【讨论】:

以上是关于CPUID 为英特尔处理器返回“GenuntellineI”的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 cpuid 获取 TLB 页面大小

如何修改KVM创建的windows的CPUID返回值

C语言怎么取CPU的各项信息?

与高级语言不同的 CPUID 使用

用C语言怎么得到电脑的CPU序列号,硬盘序列号等信息

__get_cpuid 的可移植性如何?