📄 testcpu1.cpp
字号:
// TestCpu1.cpp: implementation of the TestCpu class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "testcpu.h"
#include "TestCpu1.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
TestCpu::TestCpu()
{
clone_flag=0;
}
TestCpu::~TestCpu()
{
}
WORD TestCpu::wincpuidsupport()
{
int cpuid_support = 1;
_asm {
pushfd // Get original EFLAGS
pop eax
mov ecx, eax // EFLAGS的第21位是ID(bit)位
xor eax, 200000h // Flip ID bit in EFLAGS
push eax // Save new EFLAGS value on
// stack
popfd // Replace current EFLAGS value
pushfd // Get new EFLAGS
pop eax // Store new EFLAGS in EAX
xor eax, ecx // Can not toggle ID bit,
jnz support // Processor=80486
// if eax<>ecx, then ID bit can be flipped
mov cpuid_support,0 // Clear support flag
support:
}
return cpuid_support;
} // wincpuidsupport()
WORD TestCpu::wincpuid()
{
WORD cpuid;
BYTE cpu_type=0xff;
if ( wincpuidsupport() ) // Determine whether CPUID
// opcode is supported
{
cpuid=check_IDProc();
cpu_type=(cpuid&0x30)>>4;
}
else {
clone_flag=check_clone();
cpuid=check_8086(); // Will return FFFFh or 0
if (cpuid == 0) goto end;
cpuid=check_80286(); // Will return FFFFh or 2
if (cpuid == 2) goto end;
cpuid=check_80386(); // Will return FFFFh or 3
if (cpuid == 3) goto end; // temporarily commented out.
cpuid=4; // If the processor does not support CPUID,
// is not an 8086, 80286, or 80386, assign
// processor to be an 80486
}
end:
if (clone_flag)
cpuid = cpuid | CLONE_MASK; // Signify that a clone has been
// detected by setting MSB high
switch (cpu_type)
{
case 0: str.Format("类型:%s","标准 OEM CPU"); break;
case 1: str.Format("类型:%s","超频CPU"); break;
case 2: str.Format("类型:%s","双CPU"); break;
default: str.Format("类型:%s","保留"); break;
}
return cpuid;
} // wincpuid ()
WORD TestCpu::check_IDProc()
{
int i=0;
WORD cpu_type=0xffff;
BYTE stepping=0;
BYTE model=0;
BYTE vendor_id[12]="";
BYTE intel_id[13]="GenuineIntel";
_asm {
xor eax, eax // Set up for CPUID instruction
CPUID // Get and save vendor ID
mov dword ptr vendor_id, ebx
mov dword ptr vendor_id[+4], edx
mov dword ptr vendor_id[+8], ecx
}
for (i=0;i<12;i++)
{
if (!(vendor_id[i]==intel_id[i]))
clone_flag = 1;
}
_asm {
cmp eax, 1 // Make sure 1 is valid input
// for CPUID
jl end_IDProc // If not, jump to end
xor eax, eax
inc eax
CPUID // Get family/model/stepping/
// features
mov stepping, al
and stepping, 0x0f //0fh
and al, 0f0h
shr al, 4
mov model, al
and eax, 3f00h
shr eax, 8 // Isolate family
and al, 03fh
mov cpu_type, ax // Set _cpu_type with family
end_IDProc:
mov ax, cpu_type
}
return cpu_type;
} // Check_IDProc()
/* AX(15:14) = Reserved (mask these off in the calling code
* before using)
* AX(13:12) = Processor type (00=Standard OEM CPU, 01=OverDrive,
* 10=Dual CPU, 11=Reserved)
* AX(11:8) = CPU Family (the same 4-bit quantity as wincpuid())
* AX(7:4) = CPU Model, if the processor supports the CPUID
* opcode; zero otherwise
* AX(3:0) = Stepping #, if the processor supports the CPUID
* opcode; zero otherwise
EBX Version Information (Type, Family, Model, and Stepping ID)
Bits 7-0: Brand Index
Bits 15-8: CLFLUSH line size. (Value returned .8 = cache line size)
Bits 23-16: Reserved.
Bits 31-24: Processor local APIC physical ID
ECX Reserved
EDX Feature Information
*/
WORD TestCpu::check_clone()
{
short cpu_type=0;
_asm
{
MOV AX,5555h // Check to make sure this
XOR DX,DX // is a 32-bit processor
MOV CX,2h
DIV CX // Perform Division
CLC
JNZ no_clone
JMP clone
no_clone: STC
clone: PUSHF
POP AX // Get the flags
AND AL,1
XOR AL,1 // AL=0 is probably Intel,
// AL=1 is a Clone
MOV cpu_type, ax
}
cpu_type = cpu_type & 0x0001;
return cpu_type;
} // check_clone()
/***************************************************************
* check_8086()
*
* Inputs: none
*
* Returns:
* 0 if processor 8086
* 0xffff otherwise
***************************************************************/
WORD TestCpu::check_8086()
{
WORD cpu_type=0xffff;
_asm {
pushf // Push original FLAGS
pop ax // Get original FLAGS
mov cx, ax // Save original FLAGS
and ax, 0fffh // Clear bits 12-15 in FLAGS
push ax // Save new FLAGS value on stack
popf // Replace current FLAGS value
pushf // Get new FLAGS
pop ax // Store new FLAGS in AX
and ax, 0f000h // If bits 12-15 are set, then
cmp ax, 0f000h // processor is an 8086/8088
mov cpu_type, 0 // Turn on 8086/8088 flag
je end_8086 // Jump if processor is 8086/
// 8088
mov cpu_type, 0ffffh
end_8086:
push cx
popf
mov ax, cpu_type
}
return cpu_type;
} // check_8086()
/***************************************************************
* check_80286()
*
* Inputs: none
*
* Returns:
* 2 if processor 80286
* 0xffff otherwise
***************************************************************/
WORD TestCpu::check_80286()
{
WORD cpu_type=0xffff;
_asm {
pushf
pop cx
mov bx, cx
or cx, 0f000h // Try to set bits 12-15
push cx // Save new FLAGS value on stack
popf // Replace current FLAGS value
pushf // Get new FLAGS
pop ax // Store new FLAGS in AX
and ax, 0f000h // If bits 12-15 are clear
mov cpu_type, 2 // Processor=80286, turn on
// 80286 flag
jz end_80286 // If no bits set, processor is
// 80286
mov cpu_type, 0ffffh
end_80286:
push bx
popf
mov ax, cpu_type
}
return cpu_type;
} // check_80286()
/***************************************************************
* check_80386()
*
* Inputs: none
*
* Returns:
* 3 if processor 80386
* 0xffff otherwise
***************************************************************/
WORD TestCpu::check_80386()
{
WORD cpu_type=0xffff;
_asm {
mov bx, sp
and sp, not 3
pushfd // Push original EFLAGS
pop eax // Get original EFLAGS
mov ecx, eax // Save original EFLAGS
xor eax, 40000h // Flip AC bit in EFLAGS
push eax // Save new EFLAGS value on
// stack
popfd // Replace current EFLAGS value
pushfd // Get new EFLAGS
pop eax // Store new EFLAGS in EAX
xor eax, ecx // Can't toggle AC bit,
// processor=80386
mov cpu_type, 3 // Turn on 80386 processor flag
jz end_80386 // Jump if 80386 processor
mov cpu_type, 0ffffh
end_80386:
push ecx
popfd
mov sp, bx
mov ax, cpu_type
and eax, 0000ffffh
}
return cpu_type;
} // check_80386()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -