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

Python013

C语言怎么取CPU的各项信息?,第1张

X86处理器的型号,信息处理器家庭,高速缓存尺寸,时钟速度(频率)和制造商codename 等,存放在处理器的CPU ID寄存器组中。

通过执行CPU ID指令集查询,即可获取处理器的相关信息。CPU ID汇编指令使用使用eax作为输入参数(有时也用到ecx),eax、ebx、ecx、edx作为输出参数。

示例汇编代码如下:

mov    eax, 1

cpuid

在C语言中(VC6以上)实现方法为:

32位模式下,可使用内嵌汇编来调用cpuid指令;64位模式下,VC编译器不支持内嵌汇编,此时可使用微软提供的Intrinsics函数,来执行cpuid指令,该函数支持32位和64位,该函数包含在 <intrin.h>中。

CPUID指令的对应Intrinsics函数为如下两个:

void __cpuid(

  int CPUInfo[4],

  int InfoType

)

void __cpuidex(

  int CPUInfo[4],

  int InfoType,

  int ECXValue

)

其中InfoType参数是CPUID指令的eax参数,即功能ID。ECXValue参数是CPUID指令的ecx参数,即子功能ID。CPUInfo参数用于接收输出的eax, ebx, ecx, edx这四个寄存器。

早期的CPUID功能只要一个功能ID参数(eax),这时使用__cpuid函数。后来CPUID的功能扩展,又加了一个子功能ID(ecx)参数,这时用__cpuidex。64位环境下包含 <intrin.h>后直接调用两个系统库函数即可。

对32位环境,用内嵌汇编可自定义__cpuidex函数如下:

void __cpuidex(INT32 CPUInfo[4], INT32 InfoType, INT32 ECXValue)

{

    if (NULL==CPUInfo)    return

    _asm{

        // load. 读取参数到寄存器

        mov edi, CPUInfo    // 准备用edi寻址CPUInfo

        mov eax, InfoType

        mov ecx, ECXValue

        // CPUID

        cpuid

        // save. 将寄存器保存到CPUInfo

        mov    [edi], eax

        mov    [edi+4], ebx

        mov    [edi+8], ecx

        mov    [edi+12], edx

      }

}

利用系统库函数或是自定义的__cpuid,__cpuidex函数,获取处理器信息的2个示例代码如下:

//取得CPU厂商(Vendor)

// result: 成功时返回字符串的长度(一般为12)。失败时返回0。

// pvendor: 接收厂商信息的字符串缓冲区。至少为13字节。

int cpu_getvendor(char* pvendor)

{

    INT32 dwBuf[4]

    if (NULL==pvendor)    return 0

    // Function 0: Vendor-ID and Largest Standard Function

    __cpuid(dwBuf, 0)

    // save. 保存到pvendor

    *(INT32*)&pvendor[0] = dwBuf[1]    // ebx: 前四个字符

    *(INT32*)&pvendor[4] = dwBuf[3]    // edx: 中间四个字符

    *(INT32*)&pvendor[8] = dwBuf[2]    // ecx: 最后四个字符

    pvendor[12] = '\0'

    return 12

}

// 取得CPU商标(Brand)

// result: 成功时返回字符串的长度(一般为48)。失败时返回0。

// pbrand: 接收商标信息的字符串缓冲区。至少为49字节。

int cpu_getbrand(char* pbrand)

{

    INT32 dwBuf[4]

    if (NULL==pbrand)    return 0

    // Function 0x80000000: Largest Extended Function Number

    __cpuid(dwBuf, 0x80000000)

    if (dwBuf[0] < 0x80000004)    return 0

    // Function 80000002h,80000003h,80000004h: Processor Brand String

    __cpuid((INT32*)&pbrand[0], 0x80000002)    // 前16个字符

    __cpuid((INT32*)&pbrand[16], 0x80000003)    // 中间16个字符

    __cpuid((INT32*)&pbrand[32], 0x80000004)    // 最后16个字符

    pbrand[48] = '\0'

    return 48

}

更多CPUID的指令的细节查阅X86处理器公司的技术文件或CPUID规范可获取,这里不一一列举。

可以使用配对的数组。

结构体就是用来表示一个东西具有多个属性,用结构体就非常方便。

当然也可以把结构体每个成员拆分,如果有多个就是为每个成员定义一个数组。然后几个成员数组配对使用就是。