CPU信息获取 (二)

author : 辟邪马甲 

本节介绍CPU技术特征的获取方法

关于CPU这方面的信息,如果你有IA32的文档就会有很多有意思的发现,

具体请参考第二卷,指令集中的CPUID指令 . 在vc里采用嵌套asm指令的方法来执行该指令.

 
void  Executecpuid(DWORD veax)
{
 
//  The following 4 DWORD variable store the four registers values after cpuid
         DWORD deax;
         DWORD debx;
         DWORD decx;
         DWORD dedx;

         __asm
        {
            mov eax, veax
            cpuid                     
// 指令
            mov deax, eax
            mov debx, ebx
            mov decx, ecx
            mov dedx, edx
 }


}


 

 

不要小看这么一条小小的指令,很多内在的信息都是通过执行该指令而获得

EAX是做为指令输入参数的,

不同EAX的初始值执行后得到的EAX,EBX,ECX,EDX四个寄存器的值和对应的技术规格也是不同的.

我们来具体看一下:

Initial EAX  Value    //EAX初始值

   

经过上面几张图表我们就可以很清晰的知道每个参数以及对应的返回值所代表的具体规格!

其中,技术特征规格如下

 EAX:01H

 

EAX         Version Information: Type, Family, Model, and Stepping ID 
EBX         Bits 
7 - 0 : Brand Index
    Bits 
15 - 8 : CLFLUSH line size 
    Bits 
23 - 16 : Maximum number of logical processors  in   this  physical package.
    Bits 
31 - 24 : Initial APIC ID

ECX  Extended Feature Information 

EDX  Feature Information 



   这里ECX,EDX里面放的就是对应的技术特征信息了

            这两个寄存器的每个BIT对应的详细技术特征如下

 

 

到目前为止,应该是很清楚的了!

Exemple:

如果 返回值 DWORD dwEDX;

 

内建浮点运算协处理器(FPU) 对应的是第0位 

     if  ( (dwEdx  &  ( 0x0000001 ))  ==   0x00000001  )
    
{
                        .....SUPPORT;
    }

    
else
       .....NONSUPPORT;

Intel MMX(MMX) BIT 23

 超线程技术(HTT) BIT  28

 


    
if  ( (dwEdx  &  ( 1   <<   23 ))  ==   0x800000  )
    
{
              SUPPORT;
    }

    
else
               NONSUPPORT;

    
if  ( (dwEdx  &  ( 1   <<   28 ))  ==   0x10000000  )
    
{
            SUPPORT;
    }

    
else
            NONSUPPORT;

 

并且ECX寄存器中也存储了一部分技术特征.            

    同时我们也可以得到 CPU的 Vender ID String:

   EAX:00H   

     char  cVID[ 13 ];                          //  Store Vender ID String, contain 12 chars
    memset(cVID,  0 13 );         //  
    Executecpuid( 0 );         //  Execute cpuid instruction with eax = 0
    memcpy(cVID,  & m_ebx,  4 );                          //  ebx contains the first 4 chars
    memcpy(cVID + 4 & m_edx,  4 );     //  edx contains the middle 4 chars
    memcpy(cVID + 8 & m_ecx,  4 );     //  ecx contains the last 4 chars;

获得CPU Brand数据 

EAX = 0x80000002 ----- 0x80000004

     const  DWORD BRANDID  =   0x80000002 ;         //  brand parameter start at 0x80000002
     char  cBrand[ 49 ];                 //  Store Brand String,           contain 48 chars
    memset(cBrand,  0 49 );                 //  Initialize all chars to 0

    
for  (DWORD i  =   0 ; i  <   3 ; i ++ )             //  Execute cpuid instruction with 
     {                                        // eax = 0x80000002 to 0x80000004
        Executecpuid(BRANDID + i);              
        memcpy(cBrand 
+ i*16&m_eax, 16);    // eax, ebx, ecx, edx contain the brand string
    }


    
return  CString(cBrand);    

 

获得CPU的 SerialNumber  注意下,这个数据有的型号的CPU是没有的,所以你得到个0并不能说明什么

 


struct  SerialNumber
{
    WORD nibble[
6];            // 6 WORD nibble;

    SerialNumber()            
//constructor
    {
        memset(nibble, 
0sizeof(nibble));
    }

}
;




    Executecpuid(
1 );     //  Execute cpuid instruction with eax = 1
     bool  isSupport  =  m_edx  &  ( 1 << 18 );     //  Check if Serial Number is supported
     if  ( false   ==  isSupport)     //  not support
     {
        
return false;
    }

    memcpy(
& serial.nibble[ 4 ],  & m_eax,  4 );     //  eax is the higher 2 nibble
    
    Executecpuid(
3 );     //  Execute cpuid instruction with eax = 3
    memcpy( & serial.nibble[ 0 ],  & m_ecx,  8 );     //  ecx and edx constains the middle and first 4 nibble

 

还有其他一些信息就不一一列举了,

总之我们可以看到这么一条小小指令,

几乎吧整个CPU的信息都挖出来了!

因此,让我们记住这条强悍的指令 CPUID

 

(更多,更详细的资料请参考IA32 第二卷 CPUID指令的详细说明)

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值