Fonctionnement d'une procedure assembleur avec delphi [Résolu]

Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
- - Dernière réponse : Oniria
Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
- 4 août 2008 à 18:23
Bonjour,

j'essaye de transformer un code que j'ai trouvé et que j'aimerais écrire en delphi normal

Voici le code en question :

procedure MoveI32(const Source; var Dest; Count: Integer); Register;
ASM
        cmp   ECX,0
        Je    @JustQuit
        push  ESI
        push  EDI
        mov   ESI, EAX
        mov   EDI, EDX
    @Loop:
    Mov   AL, [ESI]
        Inc   ESI
        mov   [EDI], AL
        Inc   EDI
        Dec   ECX
        Jnz   @Loop
        pop   EDI
        pop   ESI
    @JustQuit:
end;        

Si quelqu'un pouvait me dire à quoi sert cette fonction.
Je ne comprend rien à l'assembleur mélé avec du delphi.
Comme j'ai juste ce bout de code à convertir en instruction pascal standard, je me permet de demander de l'aide.
En effet, je ne sais pas comment les valeurs "sources","dest" et "count" déclaré dans la procedure sont utilisé dans le code assembleur.
Je pense qu'il y a un rapport avec les registre ECX,ESI,EDI mais qui va ou ???

Merci pour vos réponses.

Bonne journée
Oniria
Afficher la suite 

6 réponses

Meilleure réponse
Messages postés
1023
Date d'inscription
dimanche 1 août 2004
Statut
Membre
Dernière intervention
17 août 2008
3
Merci
Salut !

@Source: EAX
@Dest: ECX
Count: EDX

Puisqu'on est en convention Resigter, les trois premiers paramètres sont passées via les registres CPU dans l'ordre, le reste est empilé.
C'est quand même con d'avoir une fonction sans savoir à quoi elle sert !

On dirait que ça copie Count octets Source dans Dest tout simplement (en passant octet par octet dans un registre intermédiaire AL).
C'est très con comme méthode en fait. Et pas optimisé du tout: elle pourrait copier 4 octets par 4 octets...

Moi je la remplacerai juste par la fonciton pascal standard Move()

Voila,
A+
Flo

Ressources Delphi, sources, tutoriaux, actu, ...: www.mx-dev.nethttp://te%3C/body

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 205 internautes nous ont dit merci ce mois-ci

Commenter la réponse de florenth
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
3
Merci
// register, facultatif puisque mode par defaut de Delphi.

// copie Source dans Dest byte par byte

procedure MoveI32(const Source; out Dest; const Count: Integer);
var pS, pD : ^byte;
    N : integer;
begin
  pS := @Source;
  pD := @Dest;
  for N := 0 to Count-1 do
  begin
    pD^ := pS^;
    inc(pS);
    inc(pD);
  end;
end;






Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 205 internautes nous ont dit merci ce mois-ci

Commenter la réponse de f0xi
Messages postés
1023
Date d'inscription
dimanche 1 août 2004
Statut
Membre
Dernière intervention
17 août 2008
0
Merci
Autant pour moi je me suis trompé dans les registres mais c'est bien une fonction de copie.
Commenter la réponse de florenth
Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
2
0
Merci
Merci bien florenth.
Ca y ai, j'ai compris, ce que je ne savais pas c'était que lorsque l'on place register à la fin de la procedure, delphi charge les paramétres dans l'ordre des registres EAX,EDX,ECX.

Ce sous programme est bien une copie d'un nombre count de source vers dest.
Je placerais le petit bout de code équivalent lorsque je l'aurais fait pour d'autres personnes. donc l'explication du code est le suivant :

cmp   ECX,0                             // comparaison de count avec 0
        Je    @JustQuit                  // si count = 0 on fini
        push  ESI                          // mise sur la pile de ESI (le but est de ne pas perturber les taches qui ont utilisé ESI avant)
        push  EDI                         // mise sur la pile de EDI
        mov   ESI, EAX               // on met la valeur de EAX dans ESI (l'adresse de source)
        mov   EDI, EDX              // on met la valeur de EDX dans EDI (l'adresse de dest)
    @Loop:                              // début d'une boucle
    Mov   AL, [ESI]                 // on prend l'octet se trouvant à l'adresse contenu dans ESI et onle met dans AL
        Inc   ESI                         // on increment ESI (l'adresse source=source+1)
        mov   [EDI], AL             // on sauvegarde en mémoire la valeur de AL à l'adresse mémoire de EDI
        Inc   EDI                        // on incrémente EDI
        Dec   ECX                    // on décrémente ECX (count=count-1)
        Jnz   @Loop                 // tant que ECX<>0 on reboucle
        pop   EDI                     // on relit l'ancienne valeur de EDI contenu dans la pile
        pop   ESI                     // on relie l'abcienne valeur de ESI contenu dans la pile
    @JustQuit:

En tout cas, merci beaucoup, ca m'enléve une sacré épine du pied.

Oniria
Commenter la réponse de Oniria
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
0
Merci
code de la fonction en asm (ollydebuger)

MOV ESI,EAX                // pS = @Source
MOV EAX,ECX                // Count' = Count
DEC EAX                    // Count' - 1
TEST EAX,EAX
JL SHORT fin               // si Count' <= 0 goto fin
INC EAX                    // Count' + 1
@@loop:
  MOVZX ECX,[BYTE DS:ESI]  // Stock Byte = pS^
  MOV [BYTE DS:EDX],CL     // Dest^ = Stock Byte
  INC ESI                  // inc(pS)
  INC EDX                  // inc(Dest)
  DEC EAX                  // dec(Count')
  JNZ SHORT loop           // si Count' > 0 goto loop
@@fin:






Commenter la réponse de f0xi
Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
2
0
Merci
Bonjour Foxi,

merci beaucoup pour la traduction de la procedure.
Honnêtement, je n'y arrivais pas vraiment car je pèche beaucoup sur les pointeur et mes tentatives n'était pas concluante (en gros, ca ne compilait même pas).
Mais, je m'accroche :)

Je vais voir dans l'aide les déclaration de "const" et de "out" dans la déclaration des paramètres car je ne sais pas à quoi ça sert par rapport à une déclaration simple.

Oniria
Commenter la réponse de Oniria