📄 cpuid.c
字号:
* Returns:
* 0 = CPU does not support the time stamp register
*
* Else
* Returns a variable of type TIME_STAMP which is composed of
* two DWORD variables. The 'High' DWORD contains the upper
* 32-bits of the Time Stamp Register. The 'Low' DWORD
* contains the lower 32-bits of the Time Stamp Register.
*
* Note: This function also sets the global variable clone_flag
***************************************************************/
struct TIME_STAMP FAR PASCAL _export winrdtsc()
{
struct TIME_STAMP timestamp; // Return variable for time
// stamp read
unsigned short u0=0; // Temporary variables
unsigned short u1=0;
unsigned short u2=0;
unsigned short u3=0;
DWORD features = wincpufeatures(); // Processor Features
if ( features & 0x00000010 ) {
RDTSC // Read Time Stamp
__asm
{
MOV CL, 16
MOV u0, AX
OPND32
SHR AX,CL
MOV u1, AX
MOV u2,DX
OPND32
SHR DX,CL
MOV u3,DX
}
}
timestamp.High = (DWORD) ( u3*65536 + u2 );
timestamp.Low = (DWORD) ( u1*65536 + u0 );
// Move two 16-bit values into one
// 32-bit value for the time stamp
// read at both the beginning and
// end of the test.
return timestamp;
} // winrdtsc
/***************************************************************
* getdllversion()
*
* Inputs: none
*
* Returns: Major and Minor version of this DLL.
*
* i.e. getdllversion() = 0x01 00
* Major Version<--|-->Minor Version
*
***************************************************************/
unsigned short FAR PASCAL _export getdllversion(void) {
unsigned short Version = VERSION;
return Version;
} // getdllversion()
// Internal Private Functions //////////////////////////////////
/***************************************************************
* check_clone()
*
* Inputs: none
*
* Returns:
* 1 if processor is clone (limited detection ability)
* 0 otherwise
***************************************************************/
static WORD 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
***************************************************************/
static WORD 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
***************************************************************/
static WORD 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
***************************************************************/
static WORD check_80386()
{
WORD cpu_type=0xffff;
_asm {
mov bx, sp
and sp, not 3
OPND32
pushf // Push original EFLAGS
OPND32
pop ax // Get original EFLAGS
OPND32
mov cx, ax // Save original EFLAGS
//xor ax, 40000h ; flip AC bit in EFLAGS
// the following 7 lines replace the xor above
mov dx, ax
OPND32
shr ax, 16
xor ax, 0004h
OPND32
shl ax, 16
mov ax, dx
/***********************************************/
OPND32
push ax // Save new EFLAGS value on
// stack
OPND32
popf // Replace current EFLAGS value
OPND32
pushf // Get new EFLAGS
OPND32
pop ax // Store new EFLAGS in EAX
OPND32
xor ax, cx // 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:
OPND32
push cx
OPND32
popf
mov sp, bx
mov ax, cpu_type
OPND32
and ax, 0000ffffh
}
return cpu_type;
} // check_80386()
/***************************************************************
* check_IDProc()
*
* Inputs: none
*
* Returns:
* CPU Family (i.e. 4 if Intel 486, 5 if Pentium(R) Processor)
*
* Note: This function also sets the global variable clone_flag
***************************************************************/
static WORD check_IDProc() // Processor can execute CPUID
// op; may be 80486 or greater
{
int i=0;
WORD cpu_type=0xffff;
BYTE stepping=0;
BYTE model=0;
BYTE vendor_id[12]="------------";
BYTE intel_id[12]="GenuineIntel";
_asm {
OPND32
xor ax, ax // Set up for CPUID instruction
CPU_ID // Get and save vendor ID
OPND32
mov word ptr vendor_id, bx
OPND32
mov word ptr vendor_id[+4], dx
OPND32
mov word ptr vendor_id[+8], cx
}
for (i=0;i<12;i++)
{
if (!(vendor_id[i]==intel_id[i]))
clone_flag = 1;
}
_asm {
OPND32
cmp ax, 1 // Make sure 1 is valid input
// for CPUID
jl end_IDProc // If not, jump to end
OPND32
xor ax, ax
OPND32
inc ax
CPU_ID // Get family/model/stepping/
// features
mov stepping, al
and stepping, 0fh
and al, 0f0h
shr al, 4
mov model, al
and ax, 0f00h
shr ax, 8 // Isolate family
and ax, 0fh
mov cpu_type, ax // Set cpu_type with family
end_IDProc:
mov ax, cpu_type
}
return cpu_type;
} // check_IDPRoc()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -