menu

秋梦无痕

一场秋雨无梦痕,春夜清风冻煞人。冬来冷水寒似铁,夏至京北蟑满城。

Avatar

取 CPU 信息

利用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);
}

评论已关闭