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
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
Bonjour, je lis ici :
Est-ce une piste ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 //This is required with Lazarus on x86: {$ASMMODE intel}
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 !
Bonjour,
pour compléter ce que dit tourlourou (), je donne une fonction complète :
et je rajoute
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;
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.
Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peut–être qu'il peut être sûr, etc.
Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
Mes 2 cts,
--
jp
Bonjour
Il y a deux methodes pour utiliser l'assembleur
Comme l'ont dit mes compères :
Tu places la directive
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 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
2) Tu souhaites créer une procedure ou fonction entièrement en assembleur
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;
Il faut alors utiliser le mot clef assembler
voir :
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;
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
pour Windows et avec FPC 3.2 (non testé)
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;
A+
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;
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
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:
Ce sont les lignes 12 et 13 (push esi et push ebx) et les lignes pop correspondantes....
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.
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]
Bonjour,
D'autres différences existent entre 32 et 64 bits comme l'usage des registres pour passer les arguments (il est préférable d'inciter explicitement le compilateur à utiliser les registres plutôt que la pile en ajoutant noframestack).
Ainsi l'exemple swap sur intel passera effectivement l'argument dans eax en 32 bits mais pas dans rax en 64 bits (plutôt rdx). Ça n'aide pas la portabilité mais je crois que c'est pour respecter la convention de fastcall.
Remarque : la multiplication du nombre de registres en 64 bits permet souvent d'éviter (ou de limiter) empilages et dépilages (push/pop) qui ne sont pas neutres en temps, surtout pour des fonctions courtes. Dans l'exemple, on peut ainsi remplacer esi et ebx par r10d et r11d et gagner ainsi 4 opérations push/pop.
Toujours pour les fonctions/procédures courtes. Il faut éviter d'utiliser l'assembleur pour des opérations accessibles simplement au langage. En effet, un code standard autorisera un inline (inopérant avec du code assembleur) qui permettra au compilateur d'éviter tout appel/retour de fonction et lui laissera le loisir de jongler avec les registres (alors que l'assembleur fixe les registres utilisés). Bien sûr, il en est autrement si l'opération nécessite beaucoup plus de code Pascal que de code assembleur (si si ça existe): exemple popcnt qui compte le nombre de bits à 1 d'un registre.
L'optimisation est un sport de combat
Salutations
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)
Bonjour,
GerardJ ne répond plus ? L'aurions-nous découragé, ce serait dommage !
Je me souviens maintenant avoir conversé (içi) avec lui il y a plus de trois ans à propos d'un code assembleur très proche de celui qu'il nous soumet maintenant.
Il est vrai qu'à l'époque nous n'avions envisagé qu'un contexte Delphi/32 bits et il est, depuis, coulé beaucoup d'eau sous les ponts, notamment la sortie de Lazarus 64bits et la généralisation des plateformes 64 bits.
Je présume qu'il cherche maintenant, pour évaluer l'environnement FPC/Lazarus, à recompiler son projet tel-quel.
Dans ce but, ce que l'on pourrait lui proposer dans un premier temps c'est des tenter de refaire l'essai mais en indiquant à Lazarus de compiler un exécutable 32bits (et non 64bit ce qu'il fait par défaut).
Il faut pour cela installer le cross-compilateur FPC/32bits. Cette discussion récente explique comment faire.
Bonjour
Concernant l'optimisation de la fonction "pos", allez voir, cette discussion, intéressante dans le forum Delphi, avec en primes, quelques fonctions en ASM.
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
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager