unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TCPUID = array [ 1 .. 4 ] of Longint;
TVendor = array [ 0 .. 11 ] of char;
type
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end ;
const
ID_BIT = $ 200000 ; // CPU ID 專用變量 EFLAGS ID bit
var
Form1: TForm1;
FUNCTION IsCPUID_Available : BOOLEAN; register;
FUNCTION GetCPUID : TCPUID; assembler; register;
FUNCTION GetCPUVendor : TVendor; assembler; register;
implementation
{ $R *.dfm }
// CPU ID ==================================================
FUNCTION IsCPUID_Available : BOOLEAN; register;
asm
PUSHFD { direct access to flags no possible, only via stack }
POP EAX { flags to EAX }
MOV EDX,EAX { save current flags }
XOR EAX,ID_BIT { not ID bit }
PUSH EAX { onto stack }
POPFD { from stack to flags, WITH not ID bit }
PUSHFD { back to stack }
POP EAX { get back to EAX }
XOR EAX,EDX { check IF ID bit affected }
JZ @exit { no, CPUID not availavle }
MOV AL,TRUE { Result=TRUE }
@exit:
END;
FUNCTION GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX { Save affected register }
PUSH EDI
MOV EDI,EAX { @Resukt }
MOV EAX, 1
DW $A20F { CPUID Command }
STOSD { CPUID[1] }
MOV EAX,EBX
STOSD { CPUID[2] }
MOV EAX,ECX
STOSD { CPUID[3] }
MOV EAX,EDX
STOSD { CPUID[4] }
POP EDI { Restore registers }
POP EBX
END;
FUNCTION GetCPUVendor : TVendor; assembler; register;
asm
PUSH EBX { Save affected register }
PUSH EDI
MOV EDI,EAX { @Result (TVendor) }
MOV EAX, 0
DW $A20F { CPUID Command }
MOV EAX,EBX
XCHG EBX,ECX { save ECX result }
MOV ECX, 4
@ 1 :
STOSB
SHR EAX, 8
LOOP @ 1
MOV EAX,EDX
MOV ECX, 4
@ 2 :
STOSB
SHR EAX, 8
LOOP @ 2
MOV EAX,EBX
MOV ECX, 4
@ 3 :
STOSB
SHR EAX, 8
LOOP @ 3
POP EDI { Restore registers }
POP EBX
END;
//==============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var cpuid:TCPUID; i:integer;
begin
if IsCPUID_Available then begin
edit1.text: = '' ;
cpuid: = GetCPUID;
// CPUIDStr: = GetCPUVendor + ' _ ' ;
for i: = 1 to 4 do edit1.text: = edit1.text + IntToHex(CPUID[i], 4 );
end else edit1.text: = ' CPUID_IS_NOT_AVAILABLE ' ;
end ;
end .
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TCPUID = array [ 1 .. 4 ] of Longint;
TVendor = array [ 0 .. 11 ] of char;
type
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end ;
const
ID_BIT = $ 200000 ; // CPU ID 專用變量 EFLAGS ID bit
var
Form1: TForm1;
FUNCTION IsCPUID_Available : BOOLEAN; register;
FUNCTION GetCPUID : TCPUID; assembler; register;
FUNCTION GetCPUVendor : TVendor; assembler; register;
implementation
{ $R *.dfm }
// CPU ID ==================================================
FUNCTION IsCPUID_Available : BOOLEAN; register;
asm
PUSHFD { direct access to flags no possible, only via stack }
POP EAX { flags to EAX }
MOV EDX,EAX { save current flags }
XOR EAX,ID_BIT { not ID bit }
PUSH EAX { onto stack }
POPFD { from stack to flags, WITH not ID bit }
PUSHFD { back to stack }
POP EAX { get back to EAX }
XOR EAX,EDX { check IF ID bit affected }
JZ @exit { no, CPUID not availavle }
MOV AL,TRUE { Result=TRUE }
@exit:
END;
FUNCTION GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX { Save affected register }
PUSH EDI
MOV EDI,EAX { @Resukt }
MOV EAX, 1
DW $A20F { CPUID Command }
STOSD { CPUID[1] }
MOV EAX,EBX
STOSD { CPUID[2] }
MOV EAX,ECX
STOSD { CPUID[3] }
MOV EAX,EDX
STOSD { CPUID[4] }
POP EDI { Restore registers }
POP EBX
END;
FUNCTION GetCPUVendor : TVendor; assembler; register;
asm
PUSH EBX { Save affected register }
PUSH EDI
MOV EDI,EAX { @Result (TVendor) }
MOV EAX, 0
DW $A20F { CPUID Command }
MOV EAX,EBX
XCHG EBX,ECX { save ECX result }
MOV ECX, 4
@ 1 :
STOSB
SHR EAX, 8
LOOP @ 1
MOV EAX,EDX
MOV ECX, 4
@ 2 :
STOSB
SHR EAX, 8
LOOP @ 2
MOV EAX,EBX
MOV ECX, 4
@ 3 :
STOSB
SHR EAX, 8
LOOP @ 3
POP EDI { Restore registers }
POP EBX
END;
//==============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var cpuid:TCPUID; i:integer;
begin
if IsCPUID_Available then begin
edit1.text: = '' ;
cpuid: = GetCPUID;
// CPUIDStr: = GetCPUVendor + ' _ ' ;
for i: = 1 to 4 do edit1.text: = edit1.text + IntToHex(CPUID[i], 4 );
end else edit1.text: = ' CPUID_IS_NOT_AVAILABLE ' ;
end ;
end .