取 CPU 信息 @ 7/15/2005

学习类
利用CPUID 汇编指令(机器码:0FH A2H, 如果你的编译器不支持CPUID 指 令,只有emit 机器码了), 该指令可以被如下CPU识别:

Intel 486 以上的CPU,
Cyrix M1 以上的CPU,
AMD Am486 以上的CPU

(1) 取CPU OEM 字符串, 判断CPU 厂商

MOV EAX,0
CPUID

Inel的CPU将返回:
EBX:756E6547H 'Genu'
EDX:49656E69H 'ineI'
ECX:6C65746EH 'ntel'

Cyrix 的CPU 将返回:
EBX:43797269H 'Cyri'
EDX:78496E73H 'xIns'
ECX:74656164H 'tead'

AMD 的CPU 将返回:
EBX:41757468H 'Auth'
EDX:656E7469H 'enti'
ECX:63414D44H 'cAMD'

(2)CPU 到底是几86, 是否支持MMX

MOV EAX,1
CPUID

EAX的8到11位就表明是几86
3 - 386
4 - i486
5 - Pentium
6 - Pentium Pro Pentium II
2 - Dual Processors

EDX 的第0位:有无FPU
EDX的第23位:CPU是否支持IA MMX

AL=1 Pentium Pro 或Pentium II

(3) 专门检测AMD的CPU信息

MOV EAX 80000001H
CPUID

如果EAX=51H, 是AMD K5
如果EAX=66H, 是K6
EDX第0 位: 是否有FPU
EDX 第23 位,CPU是否支持MMX

示例代码:
http://www.pediy.com/bbshtml/BBS6/pediy6617.htm
#include <windows.h>
#include <iostream.h>
#include <stdio.h>

int main() {
  char OEMString[13];
  char Company[64];

  int iEAXValue,iEBXValue,iECXValue,iEDXValue;
 
  _asm {
      mov eax,0
      cpuid
      mov DWORD PTR OEMString,  ebx
      mov DWORD PTR OEMString+4,  edx
      mov DWORD PTR OEMString+8,  ecx
    }
 
  OEMString[12]=0;


  if(!strcmp(OEMString, "GenuineIntel")) {
    strcpy(Company, "Intel Corporation");
  } else if(!strcmp(OEMString, "UMC UMC UMC ")) {
    strcpy(Company, "United Microelectronics Corp.");
  } else if(!strcmp(OEMString, "AuthenticAMD")) {
    strcpy(Company, "Advanced Micro Devices");
  } else if(!strcmp(OEMString, "AMD ISBETTER")) {
    strcpy(Company, "Advanced Micro Devices");
  } else if(!strcmp(OEMString, "CyrixInstead")) {
    strcpy(Company, "Cyrix Corp., VIA Inc.");
  } else if(!strcmp(OEMString, "NexGenDriven")) {
    strcpy(Company, "NexGen Inc., Advanced Micro Devices");
  } else if(!strcmp(OEMString, "CentaurHauls")) {
    strcpy(Company, "IDT\\Centaur, Via Inc.");
  } else if(!strcmp(OEMString, "RiseRiseRise")) {
    strcpy(Company, "Rise");
  } else if(!strcmp(OEMString, "GenuineTMx86")) {
    strcpy(Company, "Transmeta");
  } else if(!strcmp(OEMString, "TransmetaCPU")) {
    strcpy(Company, "Transmeta");
  } else if(!strcmp(OEMString, "Geode By NSC")) {
    strcpy(Company, "National Semiconductor");
  } else {
    strcpy(Company, "Unknown");
  }

  cout<< "This CPU's OEM String is:"<< OEMString<< endl;
  cout<< "The cpu is product by "<<Company<<endl;
 
  _asm {
      mov eax,1
      cpuid
      mov iEAXValue,eax
      mov iEBXValue,ebx
      mov iECXValue,ecx
      mov iEDXValue,edx
    }

  int iCPUType  =(0x0000F000 & iEAXValue) >> 12;
  int iCPUFamily=(0x00000F00 & iEAXValue) >> 8;
  int iCPUModel =(0x000000F0 & iEAXValue) >> 4;
  int iCPUStep  =(0x0000000F & iEAXValue);
   
  cout << "CPU Type is: "    <<iCPUType  <<endl;
  cout << "CPU Family is: "  <<iCPUFamily <<endl;
  cout << "CPU Model is: "    <<iCPUModel  <<endl;
  cout << "CPU Stepping is: " <<iCPUStep  <<endl;
 
  char Specification[49];
 
  _asm {
      mov eax,0x80000002
      cpuid
      mov DWORD PTR Specification,  eax
      mov DWORD PTR Specification+4,  ebx
      mov DWORD PTR Specification+8,  ecx
      mov DWORD PTR Specification+12,  edx
    }

  _asm {
      mov eax,0x80000003
      cpuid
      mov DWORD PTR Specification+16,  eax
      mov DWORD PTR Specification+20,  ebx
      mov DWORD PTR Specification+24,  ecx
      mov DWORD PTR Specification+28,  edx
    }

  _asm {
      mov eax,0x80000004
      cpuid
      mov DWORD PTR Specification+32,  eax
      mov DWORD PTR Specification+36,  ebx
      mov DWORD PTR Specification+40,  ecx
      mov DWORD PTR Specification+44,  edx
    }

    Specification[48]=0;
   
  cout << "CPU Specification is:" <<Specification <<endl;

  getchar();
  return 0;
}


取CPU序列号(PSN,Processor Serial numbers,处理器序列号:标识处理器特性的一组号码,包括主频、生产日期、生产编号等。只有Pentium III系列CPU才能返回序列号。):

首先确定CPU是Intel的,执行:
MOV EAX,01H
CPUID
如果返回的EDX中,低18位为1,那么这个CPU就是支持序列号的。此时EAX就是序列号的高32位。这32位对同一型号的CPU是一样的。
再执行:
MOV EAX,03H
CPUID
此时的EDX:ECX就是序列号的第64位。
要想关闭这个ID,可执行下列代码:
MOV ECX,119H
RDMSR
OR EAX,00200000H
WRMSR
一旦执行上述代码,cpu将一直不能取id,直到下次reset。

from: http://www.yourblog.org/Data/20053/240778.html
#include <windows.h>
#include <stdio.h>

bool DetectSerialNumber() {
  bool found_sn;
  _asm {
    pushfd
    pop eax // get EFLAGS into eax
    mov ebx,eax // keep a copy
    xor eax,0x200000 // toggle CPUID bit
    push eax
    popfd // set new EFLAGS
    pushfd
    pop eax // EFLAGS back into eax

    // have we changed the ID bit?
    xor eax,ebx 

    je NO_SERIAL_NUM

    // we could toggle the bit so CPUID
    // is present
    mov eax,1

    cpuid // get processor features

    // check the serial number bit
    test edx,1<<18

    jz NO_SERIAL_NUM
    mov found_sn,1
    jmp DONE
NO_SERIAL_NUM:
    mov found_sn,0
DONE:
  }
  return found_sn;
}

void ReadSerialNumber(DWORD* serial) {
  DWORD t,m,b;
  _asm {
    mov eax,1
    cpuid

    // top 32 bits are the processor
    // signature bits
    mov t,eax

    // A new CPUID code for the
    // Pentium III
    mov eax,3
    cpuid
    mov m,edx
    mov b,ecx
  }
  // copy the locals into the pointer variables passed in
  serial[0] = b;
  serial[1] = m;
  serial[2] = t;
}

// Intel recommends displaying the serial number to the user as six
// groups of four hexidecimal digits,
// (i.e., xxxx-xxxx-xxxx-xxxx-xxxx-xxxx.).
void main() {
  DWORD serial[3];
  if(DetectSerialNumber()) {
    ReadSerialNumber(serial);
    printf ("PIII Serial Number = %04X-%04X-%04X-%04X-%04X-%04X\n",
        serial [0]&0xFFFF, serial [0] >> 16,
        serial [1]&0xFFFF, serial [1] >> 16,
        serial [2]&0xFFFF, serial [2] >> 16);
  } else {
    printf("Not found serial Number\n");
  }
}


取CPU频率:(跟CPUID无关,嗯)
from: http://www.yourblog.org/Data/20053/240769.html
#include <windows.h>
#include <stdio.h>

int GetWindowsCpuFrequency() {
    DWORD eax1,edx1,eax2,edx2;
    __asm {
        rdtsc
        mov eax1,eax
        mov edx1,edx
    }
    Sleep(1000);
    __asm {
        rdtsc
        mov eax2,eax
        mov edx2,edx
    }

    eax2-=eax1;
    edx2-=edx1;

    edx2*=2147483647;
    edx2+=eax2;
    return (edx2 / 1024L / 1024L);
}
发布于 7/15/2005 12:21:19 | 评论:0

看帖要回帖...

categories
archives
links
statistics
  • 网志数:1186
  • 评论数:2015