How can I tell if I'm running on x64?

Mason, you can use IsWow64Process (WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows)

Uses Windows;

type
  WinIsWow64 = function( Handle: THandle; var Iret: BOOL ): Windows.BOOL; stdcall;


function IAmIn64Bits: Boolean;
var
  HandleTo64BitsProcess: WinIsWow64;
  Iret                 : Windows.BOOL;
begin
  Result := False;
  HandleTo64BitsProcess := GetProcAddress(GetModuleHandle('kernel32.dll'), 'IsWow64Process');
  if Assigned(HandleTo64BitsProcess) then
  begin
    if not HandleTo64BitsProcess(GetCurrentProcess, Iret) then
    Raise Exception.Create('Invalid handle');
    Result := Iret;
  end;
end;

Bye.


I see the your question 2 (are you running on Win64?) is already answered. Just keep in mind that for your code to be future-proof, you need to consider that in a (hypothetical) 64-bit Delphi app running on Win64, IsWow64Process would also return FALSE.

As regards your first question - are you on a 64-bit CPU -, you can check the hardware for the respective CPUID feature flag, like in the code below.


function Is64BitProcessor: boolean;
begin
  Result:=false;
  if CpuidAvailable = true then Result := Has64BitFeatureFlag;
end;

which uses the following two low-level functions:


function CPUIDavailable:boolean;
asm // if EFLAGS bit 21 can be modified then CPUID is available
    pushfd              //Save Flags
          pushfd        //Copy flags to EAX
          pop eax
          mov ecx,eax   //Make another copy in ECX
          btc eax,21    //Complement bit 21
          push eax      //Copy EAX to flags
          popfd
          pushfd        //Copy flags back to EAX
          pop eax
          cmp eax,ecx   //Compare "old" flags value with potentially modified "new" value
          setne al      //Set return value
    popfd               //Restore flags
end;

function Has64BitFeatureFlag: boolean; asm //IF CPUID.80000001h.EDX[bit29]=1 THEN it's a 64bit processor. //But we first need to check whether there's a function 80000001h. push ebx //Save EBX as CPUID will modify EBX push esi //Save ESI as we'll use ESI internally

xor eax,eax             //Setting EAX = input param for CPUID to 0
cpuid                   //Call CPUID.0
                        //Returns -> EAX = max "standard" EAX input value
mov esi, eax            //Saving MaxStdInput Value

mov eax,80000000h       //Setting EAX = input param for CPUID to $80000000
cpuid                   //Call CPUID.80000000h
                        //Returns -> EAX = max "extended" EAX input value
                        //If 80000000h call is unsupported (no 64-bit processor),
                        //cpuid should return the same as in call 0
cmp eax, esi
je @No64BitProcessor    //IF EAX{MaxExtInput} = ESI{MaxStdInput} THEN goto No64BitProcessor;

cmp eax, 80000001h
jb @No64BitProcessor    //IF EAX{MaxExtInput} < $80000001 THEN goto No64BitProcessor;

mov eax,80000001h       //Call $80000001 is supported, setting EAX:=$80000001
cpuid                   //Call CPUID.80000001h
                        //Checking "AMD long mode"/"Intel EM64T" feature bit (i.e., 64bit processor)
bt edx, 29              //by checking CPUID.80000001h.EDX[bit29]
setc al                 //IF Bit29=1 then AL{Result}:=1{true; it's a 64-bit processor}
jmp @Exit               //Exit {Note that Delphi may actually recode this as POP ESI; POP EBX; RET}

@No64BitProcessor: xor eax, eax //Result{AL/EAX}:=0{false; it's a 32-bit processor}; @Exit: pop esi //Restore ESI pop ebx //Restore EBX end;

EDIT1: A note on CPUIDavailable: This is of course assuming a >= 32-bit x86 processor (80386 or later), but Delphi Win32 code won't run on earlier machines anyway. The CPUID instruction was introduced with late 80486 processors.


You can check for the existence of and then call IsWow64Process. The linked MSDN page shows the required code.

Tags:

64 Bit

Delphi