2016-10-19 3 views
1

Il s'ensuit du code que je veux traduire à partir de Delphi inline assembly parce que lors de la compilation pour Win64 j'obtiens des erreurs. Le code fonctionne comme prévu lorsqu'il est compilé pour Win32.Le code BASM Delphi génère des erreurs lors du ciblage de Win64. Peut-il être converti en Pascal pur?

Nous vous remercions de votre aide.

var 
    a,b,c,d: LongWord; 
    CPUID: string; 
begin 
    asm 
    push EAX 
    push EBX 
    push ECX 
    push EDX 

    mov eax, 1 
    db $0F, $A2 
    mov a, EAX 
    mov b, EBX 
    mov c, ECX 
    mov d, EDX 

    pop EDX 
    pop ECX 
    pop EBX 
    pop EAX 

    { 
    mov eax, 1 
    db $0F, $A2 
    mov a, EAX 
    mov b, EBX 
    mov c, ECX 
    mov d, EDX 
    } 
    end; 
    CPUID := IntToHex(a,8) + '-' + IntToHex(b,8) + '-' + IntToHex(c,8) + '-' + IntToHex(d,8); 
    ShowMessage(CPUID); 
end; 
+1

Code de [ici] (http://www.swissdelphicenter.ch/fr/showcode.php?id=2044), qui permet d'obtenir des informations sur le cpuid (numéro de référence, numéro de modèle, code de famille et type de processeur). –

+1

Voir [Code d'ID de l'UC x86 de Porting Assembler sur AMD64] (http://stackoverflow.com/q/13874152/576719). –

Répondre

2

Ce code exécute une instruction de matériel natif sur les processeurs x86 et x64, CPUID. Cette instruction ne peut pas être accédée par le code Pascal natif, vous aurez donc besoin de tomber dans l'assembleur. Le code de votre question ne fonctionne pas car il mélange Pascal et l'assembleur, ce qui n'est pas autorisé dans le compilateur 64 bits, et une très mauvaise idée dans le compilateur 32 bits. Ainsi, la voie à suivre est de coder ceci comme une pure routine d'assembleur.

Il y a beaucoup d'exemples autour de comment faire ceci. Par exemple, Rodrigo Ruz a cette unité: https://github.com/RRUZ/vcl-styles-plugins/blob/master/Common/delphi-detours-library/CPUID.pas qui contient exactement ce dont vous avez besoin.

Il n'est pas très difficile de rouler les vôtres. Il pourrait se présenter comme suit:

{$APPTYPE CONSOLE} 

uses 
    System.SysUtils; 

type 
    TRegisters = record 
    EAX: UInt32; 
    EBX: UInt32; 
    ECX: UInt32; 
    EDX: UInt32; 
    end; 

function GetCPUID(ID: Integer): TRegisters; 
asm 
{$IF Defined(CPUX86)} 
    push ebx 
    push edi 
    mov edi, edx 
    cpuid 
    mov [edi+$0], eax 
    mov [edi+$4], ebx 
    mov [edi+$8], ecx 
    mov [edi+$c], edx 
    pop edi 
    pop ebx 
{$ELSEIF Defined(CPUX64)} 
    mov r8, rbx 
    mov r9, rcx 
    mov eax, edx 
    cpuid 
    mov [r9+$0], eax 
    mov [r9+$4], ebx 
    mov [r9+$8], ecx 
    mov [r9+$c], edx 
    mov rbx, r8 
{$ELSE} 
    {$Message Fatal 'GetCPUID has not been implemented for this architecture.'} 
{$IFEND} 
end; 

var 
    Registers: TRegisters; 

begin 
    Registers := GetCPUID(1); 
    Writeln(IntToHex(Registers.EAX, 8) + '-' + IntToHex(Registers.EBX, 8) + '-' + IntToHex(Registers.ECX, 8) + '-' + IntToHex(Registers.EDX, 8)); 
    Readln; 
end. 

Vous devez comprendre les conventions d'appel, la façon dont les paramètres correspondent aux registres, registres doivent être conservés, et ainsi de suite.

Avec un peu de recherche sur le Web, vous trouverez d'innombrables autres exemples. Par exemple, il y a un message Stack Overflow ici (Porting Assembler x86 CPU ID code to AMD64) qui est sans doute un doublon de cette question.

+0

Cela ne semble pas répondre à la question de savoir comment recoder l'appel CPUID afin qu'il compile OK dans le compilateur Win64 de Delphi. Comme indiqué dans la question, de telles instructions d'assemblage Win32 provoquent des erreurs de compilation. En effet spécifiquement la question demande si cela peut être recodé en Pascal afin que les problèmes d'assembleur avec Win64 peuvent être évités. – blong

+0

@blong Fair point. J'ai ajouté un paragraphe traitant de cela. –

+0

c'est vrai @blong, merci pour l'aide. dans tous les exemples l'assembly est présent ... l'erreur qui renvoie Delphi est où est 'asm' ... –