Linux C/C++ 获取CPUID

实现方式:

INTEL CC 格式

AT^T CC 格式

GCC/C库 __cpuid 宏

大致讲义:

AT^T 格式汇编很反人类,GCC可以改编译器选项为INTEL内嵌汇编,但一般在GCC还是按照默认的AT^T汇编来拽写把,不想用也可以让AI工具把INTEL内嵌汇编转换为AT^T汇编(让 bard、gpt、bing 干这种反人类的活很好用),AT^T汇编格式没有学的必要,这是一个反人类的东西。

asm volatile(

"movl $0x00, %%eax\n\t"

"xorl %%edx, %%edx\n\t"

"cpuid\n\t"

"movl %%eax, %0\n\t"

"movl %%edx, %1\n\t"

: "=m" (s1), "=m" (s2)

:

: "%eax", "%edx"

);

汇编是一种面向地址标识符及通用寄存器编程的低级语言。

IL: 把立即数0移动到EAX寄存器,CPU参数(LEVEL,CPU内置指令函数取值范围0~1)

IL: 把EDX寄存器XOR(亦或)重置为0

IL: cpuid 指令(会推送值到EAX、EBX、ECX、EDX 四个寄存器之中,SN[4])

IL: 把EAX寄存器的值复制给内链参数一(注意是压入是内存地址,%0 = s1变量)

IL: 把EDX寄存器的值复制给内链参数二(注意是压入是内存地址,%1 = s2变量)

声明内嵌所需要的寄存器与变量内存地址。

注解:

cpp 复制代码
__asm__ __volatile__ (
    "movl $0x00, %%eax\n\t"   // 将立即数 0x00 移动到 eax 寄存器中
    "xorl %%edx, %%edx\n\t"  // 将 edx 寄存器与自身进行异或操作,相当于将 edx 清零
    "cpuid\n\t"              // 执行 cpuid 指令,用于获取 CPU 的信息
    "movl %%eax, %0\n\t"     // 将 eax 寄存器的值移动到 s1 变量中
    "movl %%edx, %1\n\t"     // 将 edx 寄存器的值移动到 s2 变量中
    : "=m" (s1), "=m" (s2)   // 输出操作数列表,将 s1 和 s2 分别与 %0 和 %1 关联起来
    :                        // 输入操作数列表为空
    : "%eax", "%edx"         // 使用了 eax 和 edx 寄存器,需要在此处进行声明
);

具体实现:

cpp 复制代码
#if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
        ppp::string CPUID() noexcept { 
            int s1, s2, s3, s4;

            // int sn[4]; /* #include <cpuid.h> */
            // __cpuid(0, sn[0], sn[1], sn[2], sn[3]);
            // s1 = sn[0];
            // s2 = sn[3];

            // __cpuid(1, sn[0], sn[1], sn[2], sn[3]);
            // s3 = sn[0];
            // s4 = sn[3];

            // INTEL CC:
            // __asm 
            // {
            //     mov eax, 00h
            //     xor edx, edx
            //     cpuid
            //     mov dword ptr[s1], eax
            //     mov dword ptr[s2], edx
            // }

            // __asm 
            // {
            //     mov eax, 01h
            //     xor ecx, ecx
            //     xor edx, edx
            //     cpuid
            //     mov dword ptr[s3], eax
            //     mov dword ptr[s4], edx
            // }

            // AT&T CC
            __asm__ __volatile__(
                "movl $0x00, %%eax\n\t"
                "xorl %%edx, %%edx\n\t"
                "cpuid\n\t"
                "movl %%eax, %0\n\t"
                "movl %%edx, %1\n\t"
                : "=m" (s1), "=m" (s2)
                :
                : "%eax", "%edx"
            );

            __asm__ __volatile__(
                "movl $0x01, %%eax\n\t"
                "xorl %%ecx, %%ecx\n\t"
                "xorl %%edx, %%edx\n\t"
                "cpuid\n\t"
                "movl %%eax, %0\n\t"
                "movl %%edx, %1\n\t"
                : "=m" (s3), "=m" (s4)
                :
                : "%eax", "%ecx", "%edx"
            );

            // You can query all CPU processor instances using WQL in wbemtest, 
            // View the ProcessorId attribute of the processor instance MOF, 
            // And clarify the rules for the operating system CPUID to obtain and format as text.

            char buf[40];
            snprintf(buf, sizeof(buf), "%016llX %016llX",
                (long long unsigned int)((int64_t)s4 << 32 | (int64_t)s3),
                (long long unsigned int)((int64_t)s2 << 32 | (int64_t)s1));
            return buf;
        }
#endif
相关推荐
可均可可25 分钟前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
颇有几分姿色42 分钟前
深入理解 Linux 内存管理:free 命令详解
linux·运维·服务器
白子寰1 小时前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
小芒果_011 小时前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
gkdpjj1 小时前
C++优选算法十 哈希表
c++·算法·散列表
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
-Even-1 小时前
【第六章】分支语句和逻辑运算符
c++·c++ primer plus
AndyFrank1 小时前
mac crontab 不能使用问题简记
linux·运维·macos
筱源源1 小时前
Kafka-linux环境部署
linux·kafka
EricWang13582 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端