你也可以不使用汇编来实现这个功能。但是这种方法只适用于Windows XP及更高版本。
function IsProcessorFeaturePresent(ProcessorFeature: DWORD): BOOL; stdcall;
external kernel32 name 'IsProcessorFeaturePresent';
const
PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10;
function HasSSE2: boolean;
begin
result := IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
end;
function SupportsSSE2: LongBool;
const
CPUID_INTEL_SSE2 = $04000000;
asm
push ebx
mov eax, 1
cpuid
mov eax, FALSE
test edx, CPUID_INTEL_SSE2
jz @END
mov eax, TRUE
@END:
pop ebx
end;
function SupportsSSE2: Boolean;
? - menjaraz这是graphics32库用来检测处理器特性的代码:
{$IFDEF WIN64}
{$DEFINE TARGET_x64}
{$ENDIF}
type
TCPUInstructionSet = (ciMMX, ciEMMX, ciSSE, ciSSE2, ci3DNow, ci3DNowExt);
const
CPUISChecks: Array[TCPUInstructionSet] of Cardinal =
($800000, $400000, $2000000, $4000000, $80000000, $40000000);
{ciMMX , ciEMMX, ciSSE , ciSSE2 , ci3DNow , ci3DNowExt}
function CPUID_Available: Boolean;
asm
{$IFDEF TARGET_x64}
MOV EDX,False
PUSHFQ
POP RAX
MOV ECX,EAX
XOR EAX,$00200000
PUSH RAX
POPFQ
PUSHFQ
POP RAX
XOR ECX,EAX
JZ @1
MOV EDX,True
@1: PUSH RAX
POPFQ
MOV EAX,EDX
{$ELSE}
MOV EDX,False
PUSHFD
POP EAX
MOV ECX,EAX
XOR EAX,$00200000
PUSH EAX
POPFD
PUSHFD
POP EAX
XOR ECX,EAX
JZ @1
MOV EDX,True
@1: PUSH EAX
POPFD
MOV EAX,EDX
{$ENDIF}
end;
function CPU_Signature: Integer;
asm
{$IFDEF TARGET_x64}
PUSH RBX
MOV EAX,1
CPUID
POP RBX
{$ELSE}
PUSH EBX
MOV EAX,1
{$IFDEF FPC}
CPUID
{$ELSE}
DW $A20F // CPUID
{$ENDIF}
POP EBX
{$ENDIF}
end;
function CPU_Features: Integer;
asm
{$IFDEF TARGET_x64}
PUSH RBX
MOV EAX,1
CPUID
POP RBX
MOV EAX,EDX
{$ELSE}
PUSH EBX
MOV EAX,1
{$IFDEF FPC}
CPUID
{$ELSE}
DW $A20F // CPUID
{$ENDIF}
POP EBX
MOV EAX,EDX
{$ENDIF}
end;
function CPU_ExtensionsAvailable: Boolean;
asm
{$IFDEF TARGET_x64}
PUSH RBX
MOV @Result, True
MOV EAX, $80000000
CPUID
CMP EAX, $80000000
JBE @NOEXTENSION
JMP @EXIT
@NOEXTENSION:
MOV @Result, False
@EXIT:
POP RBX
{$ELSE}
PUSH EBX
MOV @Result, True
MOV EAX, $80000000
{$IFDEF FPC}
CPUID
{$ELSE}
DW $A20F // CPUID
{$ENDIF}
CMP EAX, $80000000
JBE @NOEXTENSION
JMP @EXIT
@NOEXTENSION:
MOV @Result, False
@EXIT:
POP EBX
{$ENDIF}
end;
function CPU_ExtFeatures: Integer;
asm
{$IFDEF TARGET_x64}
PUSH RBX
MOV EAX, $80000001
CPUID
POP RBX
MOV EAX,EDX
{$ELSE}
PUSH EBX
MOV EAX, $80000001
{$IFDEF FPC}
CPUID
{$ELSE}
DW $A20F // CPUID
{$ENDIF}
POP EBX
MOV EAX,EDX
{$ENDIF}
end;
function HasInstructionSet(const InstructionSet: TCPUInstructionSet): Boolean;
// Must be implemented for each target CPU on which specific functions rely
begin
Result := False;
if not CPUID_Available then Exit; // no CPUID available
if CPU_Signature shr 8 and $0F < 5 then Exit; // not a Pentium class
case InstructionSet of
ci3DNow, ci3DNowExt:
{$IFNDEF FPC}
if not CPU_ExtensionsAvailable or (CPU_ExtFeatures and CPUISChecks[InstructionSet] = 0) then
{$ENDIF}
Exit;
ciEMMX:
begin
// check for SSE, necessary for Intel CPUs because they don't implement the
// extended info
if (CPU_Features and CPUISChecks[ciSSE] = 0) and
(not CPU_ExtensionsAvailable or (CPU_ExtFeatures and CPUISChecks[ciEMMX] = 0)) then
Exit;
end;
else
if CPU_Features and CPUISChecks[InstructionSet] = 0 then
Exit; // return -> instruction set not supported
end;
Result := True;
end;
您可以调用HasInstructionSet(ciSSE2)
来发现您所需的内容。
Graphic32
中使用它。 - menjaraz