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
相关推荐
IC 见路不走29 分钟前
LeetCode 第91题:解码方法
linux·运维·服务器
翻滚吧键盘42 分钟前
查看linux中steam游戏的兼容性
linux·运维·游戏
小能喵1 小时前
Kali Linux Wifi 伪造热点
linux·安全·kali·kali linux
汀沿河1 小时前
8.1 prefix Tunning与Prompt Tunning模型微调方法
linux·运维·服务器·人工智能
zly35001 小时前
centos7 ping127.0.0.1不通
linux·运维·服务器
小哥山水之间2 小时前
基于dropbear实现嵌入式系统ssh服务端与客户端完整交互
linux
ldj20202 小时前
2025 Centos 安装PostgreSQL
linux·postgresql·centos
翻滚吧键盘2 小时前
opensuse tumbleweed上安装显卡驱动
linux
黑听人3 小时前
【力扣 简单 C】70. 爬楼梯
c语言·leetcode
杜子不疼.3 小时前
二分查找,乘法口诀表,判断闰年,判断素数,使用函数实现数组操作
c语言