IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Insérer de l'assembleur dans Lazarus


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Inscrit en
    Novembre 2008
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 69
    Billets dans le blog
    1
    Par défaut Insérer de l'assembleur dans Lazarus
    Bonjour,
    J'utilisais Delphi et j'essaie d'utiliser maintenant Lazarus. Dans Delphi, je savais insérer directement de l'assembleur en commençant par asm.
    Cela génère une erreur dans Lazarus.
    Y a-t-il une solution ?
    merci

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 937
    Billets dans le blog
    6
    Par défaut
    Bonjour, je lis ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      //This is required with Lazarus on x86:
      {$ASMMODE intel}
    Est-ce une piste ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 142
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 142
    Par défaut
    Bonjour,

    pour compléter ce que dit tourlourou (), je donne une fonction complète :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function Swap32_si_Moto(C : Cardinal) : Cardinal;
    var
     S : Cardinal;
    begin
      {$ASMMODE intel} // nécessaire si pas {$mode delphi} + couple begin/end
      asm
        bswap EAX // C est passé dans EAX et bswap échange les octets 0123 -> 3210
        mov   S, EAX
      end;
      if Motorola then Result := S else Result := C;
    end;
    et je rajoute
    Citation Envoyé par GerardJ Voir le message
    Cela génère une erreur dans Lazarus.
    qu'une bonne pratique sur les forums consiste à donner l'erreur, sinon on perd du temps à poser la question "et c'est quoi l'erreur ?" puis à attendre la réponse, ici ça allait, c'était facile.

  4. #4
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Bonjour

    Il y a deux methodes pour utiliser l'assembleur

    Comme l'ont dit mes compères :
    Tu places la directive

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Unit Unit1;
     
    {$mode objfpc}{$H+} 
    {$asmmode intel} // si non par defaut c'est le mode ATT&T. Voir aussi dans les options du projet
     
    Interface
    1) Tu souhaites imbriquer de l'assembleur dans du code natif

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure DoSomething;
    var
     i: integer
    begin
      for i:= 0 to 9 do
      begin
        asm
           // ton code asm ici
        end;
      end;
    end;
    2) Tu souhaites créer une procedure ou fonction entièrement en assembleur
    Il faut alors utiliser le mot clef assembler

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function doSomething : byte; assembler;
    asm
      // ton code assembleur ici
    end;
     
    procedure doSomething; assembler;
    asm
      // ton code assembleur ici
    end;
    voir :
    https://wiki.freepascal.org/Asm
    https://wiki.freepascal.org/Assembler_and_ABI_Resources

    Tu disposes en plus du mot clef assembler de : Register, nostackframe et vectorcall ce dernier étant dispo uniquement à partir de FPC 3.2 et uniquement pour Windows et les instructions SIMD

    exemple :

    pour Windows et avec FPC 3.0.4

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function TBZVector4f.DivideBy2:TBZVector4f;assembler; nostackframe; register;
    asm
      movaps xmm0,[RCX]
      mulps xmm0, XMMWORD PTR [RIP+cHalfOneVector4f]
      movaps [RESULT],xmm0
    end;
    pour Windows et avec FPC 3.2 (non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function TBZVector4f.DivideBy2:TBZVector4f;assembler; vectorcall;
    asm
      mulps xmm0, XMMWORD PTR [RIP+cHalfOneVector4f]
      movaps [RESULT],xmm0 
    end;
    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  5. #5
    Membre confirmé

    Inscrit en
    Novembre 2008
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 69
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Bonjour,

    pour compléter ce que dit tourlourou (), je donne une fonction complète :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function Swap32_si_Moto(C : Cardinal) : Cardinal;
    var
     S : Cardinal;
    begin
      {$ASMMODE intel} // nécessaire si pas {$mode delphi} + couple begin/end
      asm
        bswap EAX // C est passé dans EAX et bswap échange les octets 0123 -> 3210
        mov   S, EAX
      end;
      if Motorola then Result := S else Result := C;
    end;
    et je rajoute

    qu'une bonne pratique sur les forums consiste à donner l'erreur, sinon on perd du temps à poser la question "et c'est quoi l'erreur ?" puis à attendre la réponse, ici ça allait, c'était facile.
    Merci ça marche sauf que cela génère une erreur que je n'ai pas dans Delphi...
    joueur.pas(391,8) Error: Asm: [push reg32] invalid combination of opcode and operands
    le code :
    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
            MOV  EAX, Substr
            MOV  EDX, S
            MOV  ECX, &Offset
           test  eax, eax
           jz    @Nil
           test  edx, edx
           jz    @Nil
           dec   ecx
           jl    @Nil
     
           push  esi
           push  ebx
     
           mov   esi, [edx-4]  //Length(Str)
           mov   ebx, [eax-4]  //Length(Substr)
           sub   esi, ecx      //effective length of Str
           add   edx, ecx      //addr of the first char at starting position
           cmp   esi, ebx
           jl    @Past         //jump if EffectiveLength(Str)<Length(Substr)
           test  ebx, ebx
           jle   @Past         //jump if Length(Substr)<=0
     
           add   esp, -12
           add   ebx, -1       //Length(Substr)-1
           add   esi, edx      //addr of the terminator
           add   edx, ebx      //addr of the last char at starting position
           mov   [esp+8], esi  //save addr of the terminator
           add   eax, ebx      //addr of the last char of Substr
           sub   ecx, edx      //-@Str[Length(Substr)]
           neg   ebx           //-(Length(Substr)-1)
           mov   [esp+4], ecx  //save -@Str[Length(Substr)]
           mov   [esp], ebx    //save -(Length(Substr)-1)
           movzx ecx, byte ptr [eax] //the last char of Substr
     
    @Loop:
           cmp   cl, [edx]
           jz    @Test0
           jmp   @Exit
    @AfterTest0:
           cmp   cl, [edx+1]
           jz    @TestT
    @AfterTestT:
           add   edx, 4
           cmp   edx, [esp+8]
           jb   @Continue
    @EndLoop:
           add   edx, -2
           cmp   edx, [esp+8]
           jb    @Loop
    @Exit:
           add   esp, 12
    @Past:
           pop   ebx
           pop   esi
    @Nil:
           xor   eax, eax
           //ret
           jmp  @Fin
    @Continue:
           cmp   cl, [edx-2]
           jz    @Test2
           cmp   cl, [edx-1]
           jnz   @Loop
    @Test1:
           add   edx,  1
    @Test2:
           add   edx, -2
    @Test0:
           add   edx, -1
    @TestT:
           mov   esi, [esp]
           test  esi, esi
           jz    @Found
    @String:
           movzx ebx, word ptr [esi+eax]
           cmp   bx, word ptr [esi+edx+1]
           jnz   @Exit
           cmp   esi, -2
           jge   @Found
           movzx ebx, word ptr [esi+eax+2]
           cmp   bx, word ptr [esi+edx+3]
           jnz   @Exit
           add   esi, 4
           jl    @String
    @Found:
           mov   eax, [esp+4]
           add   edx, 2
     
           cmp   edx, [esp+8]
           ja    @Exit
     
           add   esp, 12
           add   eax, edx
           pop   ebx
           pop   esi
    @Fin:

  6. #6
    Membre confirmé

    Inscrit en
    Novembre 2008
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 69
    Billets dans le blog
    1
    Par défaut
    Ce sont les lignes 12 et 13 (push esi et push ebx) et les lignes pop correspondantes....

  7. #7
    Membre émérite

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Par défaut
    Bonjour GerardJ,

    Si tu compile pour une plateforme cible 64bits il est possible que tu ne puisse pas PUSHer/POPer des registres 32 bits, ce qui correspondrait bien au message d'erreur constaté.

    Essai de PUSHer/POPer RSI et RBX au lieu de ESI et EBX.

  8. #8
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    8 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 8 055
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Citation Envoyé par DomDA91 Voir le message
    Si tu compile pour une plateforme cible 64bits il est possible que tu ne puisse pas PUSHer/POPer des registres 32 bits, ce qui correspondrait bien au message d'erreur constaté.

    Essai de PUSHer/POPer RSI et RBX au lieu de ESI et EBX.
    Exactement, en 64 bits il est possible de pusher des registres 64 bits et 16 bits (moyennant préfixe) mais pas 32 bits.
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

Discussions similaires

  1. [Lazarus] Assembleur dans Lazarus sous Ubuntu
    Par pedestre dans le forum Lazarus
    Réponses: 1
    Dernier message: 30/01/2014, 20h59
  2. [Lazarus] Assembleur dans Lazarus ?
    Par Chin Tao dans le forum Lazarus
    Réponses: 2
    Dernier message: 13/09/2007, 10h22
  3. [CR] insérer une image paramétrer dans une étiquette
    Par yoyothebest dans le forum SAP Crystal Reports
    Réponses: 6
    Dernier message: 22/08/2004, 11h58
  4. EDI pour intégrer efficacement de l'assembleur dans du C/C++
    Par Selenite dans le forum Choisir un environnement de développement
    Réponses: 2
    Dernier message: 04/04/2004, 18h27
  5. Comment insérer de l'unicode dans un Richedit ?
    Par DanaKil dans le forum C++Builder
    Réponses: 6
    Dernier message: 30/03/2004, 00h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo