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

x86 32-bits / 64-bits Assembleur Discussion :

MAJ d'une STRUCT dans une PROC


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 51
    Points : 28
    Points
    28
    Par défaut MAJ d'une STRUCT dans une PROC
    Bonjour,

    J'aimerais passer l'adresse d'une variable STRUCTURE à une PROC et modifier dans cette proc certaines zones de la Stucture.

    Imaginons une structure comme celle ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    API_ STRUCT
    	Module 		DWORD ?
    	APIName 	DWORD ?
    	APIaddr		DWORD ?	
    API_ ENDS
     
    	mystruct1 API_ <>
    	mystruct2 API_ <>
    Je connais 2 façons d'accéder à une zone d'une structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mov eax,mystruct1.Module
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    mov ebx, offset mystrcut1
    mov eax,[ebx].API_.Module
    Mon problème est que j'aimerais appeler une PROC avec en parametre l'adresse de la variable Structure pour pouvoir modifier DANS la PROC certaines zones de la structure !

    Par exemple quelque chose comme cela

    Code : 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
    Api_ STRUCT
    APIADDR    DWORD      ?
    Api_ ENDS
     
    .data
    info1 Api_ <>
    info2 Api_ <>
     
    .code
    invoke GetFnAddr,CTEXT ("user32.dll"),CTEXT ("MessageBoxA"), OFFSET info1
    invoke GetFnAddr,CTEXT ("Kernel32.dll"),CTEXT ("OpenFile"), OFFSET info2
     
    GetFnAddr Proc ModuleIn :DWORD, APIin:DWORD, Structin:DWORD
       Invoke GetModuleHandle,ModuleIn
       Invoke GetProcAddress,EAX,APIin
     
       mov [Structin].API_.APIADDR,eax
     
        Ret
    GetFnAddr endp
    Ici cela ne fonctionne pas car [Structin] est une addresse relative au stack et non pas l'addresse de ma structure

    Le seul moyen que j'ai trouvé est de ne PAS passer l'adresse de ma structure comme variable et d'utiliser un pointer vers l'adresse de mes structures par exemple

    Code : 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
    Api_ STRUCT
    APIADDR    DWORD      ?
    Api_ ENDS
     
    .data
    info1 Api_ <>
    info2 Api_ <>
     
    .code
    mov edi, offset info1
    invoke GetFnAddr,CTEXT ("user32.dll"),CTEXT ("MessageBoxA")
    mov edi, offset info2
    invoke GetFnAddr,CTEXT ("Kernel32.dll"),CTEXT ("OpenFile")
     
    GetFnAddr Proc ModuleIn :DWORD, APIin:DWORD
      Invoke GetModuleHandle,ModuleIn
      Invoke GetProcAddress,EAX,APIin
     
      mov [edi.API_.APIADDR],eax
     
       Ret
    GetFnAddr endp
    Mais n'est il pas possible de passer en paramètre d'une PROC l'adresse d'une structure et de modifier dans cette proc les zones de la structure directement ????

    Quelque chose comme mon premier exemple (mov [Structin].API_.APIADDR,eax) mais qui puisse modifier mes structures ?

    Je trouverais ça pratique de pouvoir passer une structure en parametre, modifier les zones, et retourner l'adresse de cette structure ou d'une autre
    (on passe alors qu'un pointer et non pas plein de variables)


    Merci par avance

    Pascal

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 51
    Points : 28
    Points
    28
    Par défaut
    Bon et bien j'arrive à plusieurs choses, mais mettre à jour une Structure GLOBALE depuis une procédure n'est pas si facile

    1- Une proc à besoin de LIRE tous les zones de la Struct

    Code : 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
    THESTRUCT STRUCT
       Zone1 DWORD ?
       Zone2 DWORD ?
    THESTRUCT ENDS
     
    .data
    MyStruct THESTRUCT <>
     
    .code
    ...
    Invoke MyProc,var1,var2,MyStruct
     
    Proc MyProc var1:DWORD, var2:DWORD, StructIn:THESTRUCT
        ...
        mov eax, StructIn.Zone1
    MyProc endP
    2- Une API à besoin de l'addresse de la structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    THESTRUCT STRUCT
       Zone1 DWORD ?
       Zone2 DWORD ?
    THESTRUCT ENDS
     
    .data
    MyStruct THESTRUCT <>
     
    .code
    ...
    Invoke MyProc,var1,var2, addr MyStruct
     
    Proc MyProc var1:DWORD, var2:DWORD, StructIn:DWORD
     
    MyProc endP
    3- Acceder et METTRE A JOUR des zones struct dans une PROC
    Code : 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
    THESTRUCT STRUCT
       Zone1 DWORD ?
       Zone2 DWORD ?
    THESTRUCT ENDS
     
    .data
    MyStruct THESTRUCT <>
     
    .code
    ...
    Invoke MyProc,var1,var2,addr MyStruct
     
    Proc MyProc var1:DWORD, var2:DWORD, StructIn:DWORD
        ...
        mov eax, Structin
        mov [eax].THESTRUCT.Zone1,varx
     
    MyProc endP
    Il existe aussi une autre notation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        mov eax, Structin
        mov (THESTRUCT PTR [eax]).Zone1,eax
    Mais pour une raison inconnue elle ne fonctionne pas dans certains cas, et entre autre après un .IF

    Bon voila, je pensais qu'il y avait des moyens plus simples...

    Mais peut être que vous avez mieux ?

    Merci

  3. #3
    Membre actif

    Inscrit en
    Février 2009
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 200
    Points : 235
    Points
    235
    Par défaut
    Pascal,

    Le post est ancien mais toujours sans réponse extérieure. Je suis certain que tu as entièrement fait le tour de cette question de base, aussi je me permets juste de compléter ce que tu dis afin que plusieurs puissent comprendre les enjeux de ta question.

    Le plus simple est de déclarer l'architecture de tes structures sous forme de structures de constantes. Des descripteurs en quelque sorte, équivalents au rôle des fichiers .h pour des HLL comme les C/C++.

    Tu accèdes aux divers membres de tes structures grâce aux offsets de déplacement représentés par tes structures de constantes.
    Chaque outil utilisé pour assembler du code proposant ses propres moyens pour y parvenir, je le rédige sous une sorte de forme générique afin que chacun puisse l'adapter selon l'état de l'art.

    Imaginons que tu travailles avec des datas virtuelles:

    - Tu déclares un espace mémoire d'une manière quelconque, par exemple:
    [MaStructureDeDatas: BYTE ? 256]

    Soit une structure de taille FF sans membres apparents.

    - Déclaration de ta structure sous forme d'offsets de déplacement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    [MaStructureDeDatas.Membre01 00
    MaStructureDeDatas.Membre02 04 (la taille du membre 01 est d'un DWORD (4 bytes)
    MaStructureDeDatas.Membre03 06 (la taille du membre 02 est d'un WORD (2 bytes) 
    MaStructureDeDatas.Membre04 08 (la taille du membre 03 est d'un WORD (2 bytes)
    MaStructureDeDatas.Membre05 0A (la taille du membre 04 est d'un BYTE (1 bytes)
    MaStructureDeDatas.Membre06 0B (la taille du membre 05 est d'un BYTE (1 byte)
    …. 
    MaStructureDeDatas.Membrexx FF]
    (la taille du membre xx est d'un BYTE (1 byte) puisque la taille de ta structure
    est de 256 bytes (FF base 0).
    J'ai répété le nom générique de la structure et ajouté un séparateur "." mais tu t'organises comme bon te sembles à partir du moment ou tu conserves toujours les mêmes conventions, ton code sera ainsi maintenu plus facilement dans quelques mois voir nettement plus tard...

    - Attention de toujours aligner tes datas membres de la plus grande taille vers la plus petite et à compenser les décalages au besoin:

    • Un QWORD est toujours QWORD aligné

    • Un DWORD est toujours DWORD aligné etc.
    Si tu ne la fais pas, tu subiras tes pénalisations d'accès qui ralentiront ton code inutilement.

    Pour accéder à un membre de ta structure objet (puisque tu peux appliquer cela à n'importe quel bout de mémoire réservée d'une manière ou d'une autre):

    [MaStructureDeDatas2: ? 256*bytes]
    [MaStructureDeDatas3: ? 256*bytes]

    Ou même un Lp sur une structure de datas déclarée en dur et modifiée au run-time.

    Mov ax [LpAdressedeBaseDeMaStructure + MaStructureDeData.Membre02]

    Pour l'adresse:
    Lea eax [LpAdressedeBaseDeMaStructure + MaStructureDeData.Membre02]

    Cela te permet aussi d'utiliser esi edi pour des recherches, des substitutions ou des déplacements\copies entres diverses structures objet.

    Cela te permet d'utiliser un registre pour contenir l'offset:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
           Base + Déplacement
    Mov eax [ebx+edx]
    C'est un principe utilisé dans toutes les technologies de type COM par exemple, avec des offsets communs et des héritages qui permettent de constituer des structures gigognes.

    La transmission de données organisées sera donc réduite, effectivement, à une simple transmission de Lp. Toutes les API sont aussi basées sur ce principe.

    Tes membres pouvant être des Lp sur des datas ou du code tu peux imaginer les architectures les plus diverses et les plus efficaces.
    Si tes structures sont des Lp sur des adresses de code, tu peux aussi les rendre dynamique (les Lp) en utilisant le contenu du contenu du Lp:
    Mov eax [Ebx+MaStructureDeDatas.Membre01]
    Call [eax] argument(s)

    Mais c'est une autre histoire…

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 51
    Points : 28
    Points
    28
    Par défaut
    Bonjour Rémi

    merci beaucoup pour cette réponse !

    j'ai en effet depuis, découvert que les API fonctionnaient généralement comme cela....

    Mais tu as raison de le noter et ton explication est très claire.

    >Encore merci

    Pascal

Discussions similaires

  1. [XL-2007] Afficher une checkbox dans une feuille si une checkbox d'une autre feuille est cochée
    Par JessieCoutas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/08/2009, 13h35
  2. portée d'une variable dans une fonction dans une méthode
    Par laurentg2003 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2009, 19h05
  3. [POO] dans une classe, appeler une fonction dans une méthode
    Par arnaudperfect dans le forum Langage
    Réponses: 3
    Dernier message: 26/08/2007, 23h04
  4. Envoyer une formulaire dans une page dans une Frame
    Par zooffy dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 29/06/2007, 10h13
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48

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