PDA

Ver la Versión Completa : Ayuda con lenguaje- ¿Que corres, 32 ó 64 bits?


Mav
19-04-2018, 01:26:25
Hola, tengo este código funcionando perfectamente:

program ProjectQuewin;

uses
WinApi.Windows;
// {$R *.RES}
var
caption:PChar = 'Arquitectura';
ptext: PChar = 'Estas en 32 bits';
ptext2: PChar = 'Estas en 64 bits';

begin
asm
// pushad
xor eax, eax
mov ax, es
ror ax, 3
and eax, 1
test eax, eax
je @treintaydos
push MB_OK or MB_ICONINFORMATION
push caption
push ptext2
push 0
call MessageBox
jmp @exit

@treintaydos:
push MB_OK or MB_ICONINFORMATION
push caption
push ptext
push 0
call MessageBox
@exit:
push 0
call ExitProcess
//popad

end;

end.

...pero intento meter menos ensamblador y mas pascal,
no veo como utilizar el resultado del "test eax,eax", osea, el estado del Zero Flag, directamente en pascal
se ahorraria code, declaraciones y la salida del programa etc lo manejaria el compilador
...algo así :

program quewind;
uses
WinApi.Windows;


//{$R *.res}
??????????
begin
asm

xor eax, eax
mov ax, es
ror ax, 3
and eax, 1
test eax, eax
?????????
end;
if Zero flag es cero then

MessageBox(0,'You are running 64 bit','Architecture',MB_OK or MB_ICONINFORMATION);

...y si es uno
MessageBox(0,'You are running 32 bit','Architecture',MB_OK or MB_ICONINFORMATION);
end.


Saludos

Casimiro Notevi
19-04-2018, 10:06:43
También puedes hacer todo sin ensamblador, ejemplo:

unit Unit4;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

const
PROCESSOR_ARCHITECTURE_AMD64 = 9;
{$EXTERNALSYM PROCESSOR_ARCHITECTURE_AMD64}
PROCESSOR_ARCHITECTURE_IA64 = 6;
{$EXTERNALSYM PROCESSOR_ARCHITECTURE_IA64}

type
TForm4 = class(TForm)
bt1: TButton;
procedure bt1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form4: TForm4;

implementation

{$R *.dfm}

function GetNativeSystemInfo(var SystemInfo: TSystemInfo): Boolean;
type
TGetNativeSystemInfo = procedure (var SystemInfo: TSystemInfo); stdcall;
var
LibraryHandle: HMODULE;
_GetNativeSystemInfo: TGetNativeSystemInfo;
begin
Result := False;
LibraryHandle := GetModuleHandle(kernel32);
//
if LibraryHandle <> 0 then
begin
_GetNativeSystemInfo := GetProcAddress(LibraryHandle, 'GetNativeSystemInfo');
if Assigned(_GetNativeSystemInfo) then
begin
_GetNativeSystemInfo(SystemInfo);
Result := True;
end
else
GetSystemInfo(SystemInfo);
end
else
GetSystemInfo(SystemInfo);
end;

function IsWindows64: Boolean;
var
ASystemInfo: TSystemInfo;
begin
GetNativeSystemInfo(ASystemInfo);
Result := ASystemInfo.wProcessorArchitecture in
[PROCESSOR_ARCHITECTURE_IA64, PROCESSOR_ARCHITECTURE_AMD64];
end;


procedure TForm4.bt1Click(Sender: TObject);
begin
if IsWindows64 then
ShowMessage('Es 64 bits')
else
ShowMessage('Es 32 bits');
end;

end.

Mav
20-04-2018, 20:36:17
Gracias Casimiro, lo probé, funciona tambien, he pobado otra cosa que aparentemente funciona, aunque
cogido por un pelo, no me convence del todo:

program Project1;


uses
WinApi.Windows;
// {$R *.RES}

function GetFlagZ:Boolean;
asm
xor eax, eax
mov ax, es
ror ax, 3
and eax, 1
//test eax, eax
end;

begin

GetflagZ;
if GetflagZ then
MessageBox(0,'You are running 64 bit','Architecture',MB_OK or MB_ICONINFORMATION)
else
MessageBox(0,'You are running 32 bit','Architecture',MB_OK or MB_ICONINFORMATION);

end.


...se supone que en este caso eax va a ser uno o cero, cero en caso de 32 bits ( flag ZF a 1), uno en caso de 64 bits (flag ZF a cero), entonces le estoy haciendo
trampas al compilador....
Se puede también ver si es 32 ó 64 accediendo al TEB (https://en.wikipedia.org/wiki/Win32_Thread_Information_Block) así:
......................
..........................
4 FS:[0x3C] NT Address of CSR Client Thread
4 FS:[0x40] NT Win32 Thread Information
124 FS:[0x44] NT, Wine Win32 client information (NT), user32 private data (Wine), 0x60 = LastError (Win95), 0x74 = LastError (WinME)

4 FS:[0xC0] NT Reserved for Wow64. Contains a pointer to FastSysCall in Wow64.

4 FS:[0xC4] NT Current Locale
4 FS:[0xC8] NT FP Software Status Register
.......................
.................

program winteb;

uses
WinApi.Windows;

//{$R *.res}

var
caption: PChar = 'Arquitectura';
message2: PChar = 'Estas en 32 bits';
message1: PChar = 'Estas en 64 bits';

begin
asm
xor eax,eax
mov eax, [fs:$0C0 ]
test eax,eax
je @@tredos
push MB_OK+MB_ICONINFORMATION
push caption
push message1
push 0
call MessageBox
jmp @@exit
@@tredos :
push MB_OK+MB_ICONINFORMATION
push caption
push message2
push 0
call MessageBox
@@exit:
push 0
call ExitProcess

end;

end.


...en este caso no se le pueden hacer trampas al compilador, no funciona..pero se me ha ocurrido otra cosa, vi en el código de "Detours":

function ___IsCPUIDSupported: Boolean;
asm
{$IFDEF CPUX86}
PUSH ECX
PUSHFD
POP EAX { EAX = EFLAGS }
MOV ECX, EAX { Save the original EFLAGS value . }
... voy a crear una funcion que me de como result los eflagss y luego
sólo habria que comprobar si el bit correspondiente al ZeroFlag está a cero o uno.....
Ya os lo contaré...
Saludos

Ñuño Martínez
23-04-2018, 21:01:11
Parece que es la moda estos días, ¿no? (http://www.clubdelphi.com/foros/showpost.php?p=525823&postcount=2) :D

escafandra
24-04-2018, 18:14:35
Los dos sistemas propuestos para saber si la arquitectuta del S.O. es de 32 o 64 bits pueden escribirse en delphi de esta forma, teniendo en cuenta que el resultado de una función siempre se devuelve en el registro eax:


function Is64OS: boolean;
asm
xor eax, eax
mov ax, es
ror ax, 3
and eax, 1
end;

function Is64OS_: boolean;
asm
xor eax,eax
mov eax, fs:[$0C0]
end;


Su uso sería así:

begin
if Is64OS then
ShowMessage('S.O. de 64bits')
else
ShowMessage('S.O. de 32bits');
end;


Saludos.

Mav
25-04-2018, 00:43:41
Perfecto!.Escafandra, eso es lo que buscaba,:)
Gracias
Saludos

escafandra
25-04-2018, 13:21:28
Mil perdones, hay un pequeño error en el código que expuse arriba, la función debe devolver LongBool, no boolean:

function Is64OS_: LongBool;
asm
xor eax,eax
mov eax, fs:[$0C0]
end;


Saludos.