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

Autres architectures Assembleur Discussion :

[ARM] Appel d'une fonction dans une dll


Sujet :

Autres architectures Assembleur

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 6
    Points : 8
    Points
    8
    Par défaut [ARM] Appel d'une fonction dans une dll
    Bonjour,

    j'essaye de m'initier a l'assembleur ARM et j'aurais quelques questions.
    J'ai un exe qui appelle une fonction declarée dans une DLL comme montrée ci dessous

    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
    23
     
     
    __declspec(dllimport)  void MyOutputDebugString(LPCTSTR lpOutputString);
     
    //-- EXE --
    int _tmain(int argc, _TCHAR* argv[])
    {
    	MyOutputDebugString(L"ORIGINAL FUNCTION\n");	
    	return 0;
    }
     
    //-- DLL
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
        return TRUE;
    }
    void MyOutputDebugString(LPCTSTR lpOutputString)
    {
    	OutputDebugString(lpOutputString);
    }

    Lorsque je decompile avec visual le process en train de tourner voici ce que j'obtiens :
    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
     
    wmain:
    00011000 E1A0C00D         mov         r12, sp 
    00011004 E92D0003         stmdb       sp!, {r0, r1} 
    00011008 E92D5000         stmdb       sp!, {r12, lr} 
    0001100C E24DD004         sub         sp, sp, #4 
    00011010 E59F0024         ldr         r0, [pc, #0x24] 
    00011014 E59F301C         ldr         r3, [pc, #0x1C] 
    00011018 E5933000         ldr         r3, [r3] 
    0001101C E1A0E00F         mov         lr, pc 
    00011020 E1A0F003         mov         pc, r3 
    00011024 E3A03000         mov         r3, #0 
    00011028 E58D3000         str         r3, [sp] 
    0001102C E59D0000         ldr         r0, [sp] 
    00011030 E28DD004         add         sp, sp, #4 
    00011034 E89DA000         ldmia       sp, {sp, pc} 
    00011038 0001302C         andeq       r3, r1, r12, lsr #32 
    0001103C 0001201C         andeq       r2, r1, r12, lsl r0
    Il faut savoir que sur ARM les 4 premiers paramètres d'une fonction sont passées par les registres R0 a R3, les suivants le sont sur la pile.
    Dans mon exemple j'ai choisi une fonction avec un seul argument.
    Donc si on suit le programme on a :

    mov r12, sp : sauve le pointeur de pile(SP) ds R12
    stmdb sp!, {r0, r1} : sauve le registre R0 et R1 sur la pile et dec SP
    stmdb sp!, {r12, lr} : sauve le registre R12 et LR sur SP et dec SP
    sub sp, sp, #4 : alloue 4 octets sur la pile
    ldr r0, [pc, #0x24] : mets dans R0 le contenu de l'adresse de PC avec un index de 0x24

    C'est cette ligne avec laquelle j'ai du mal
    En fait juste avant l'exécution de cette instruction PC = 0x00011010
    et apres exécution j'ai R0 = 0x0001201c. Quand je regarde l'espace mémoire a cette adresse j'ai bien L"ORIGINAL FUNCTION\n", le premier paramètre de ma fonction.
    Cependant la syntaxe [pc, #0x24] je ne comprends pas. Au debut je pensais que ca signifiait que l'on prends la valeur du PC et que l'on ajoute 0x24 ce qui me donnerait 0x00011010+0x24 = 0x11034 mais a 0x11034 j'ai E89DA000 cad
    ldmia sp, {sp, pc} . Donc si quelqu'un pouvait m'éclairer sur le sujet...

  2. #2
    Candidat au Club
    Inscrit en
    Mars 2007
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Salut!

    Je travaille aussi sur les Call ARM et c'est un sacré foutoir!

    Je suppose que PC + #0x24 est l'adresse de ta chaine... qu'il met dans R0 pour la passer en argument à ta fonction qui est à l'adresse PC + 0x1C, mais je trouve ca assez bizarre aussi....

    Si tu es sous VS2005 tu peux modifier les affichages avec un clic droit dans le fenêtre de Disassembly.

    En debug, le compilateur fait certaines opérations parfois inutiles du genre "sauver les registres dans la pile à l'entrée dans une fonction", alors qu'il ne le fera pas en release, comme STMDB SP! {R0,R1}. D'ailleurs, si quelqu'un a des infos là-dessus je suis preneur! Pourquoi en debug on met R0-R3 dans la pile avant de les recharger pour les utiliser???

    edit: au passage, le compilateur fait-il souvent SUB SP, SP, #4 pour se libérer un accès à la pile??? pourquoi pas un STMDB ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2007
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    salut,

    tu devrais avoir E89DA00 dans r0 à la fin du programme, seulement entre temps tu fais un chargement dans r0 :
    ldr r0, [sp]

    deuxième piste : à quel moment vérifie tu la valeur de r0 exactement ? car à la suite du programme n'importe quoi peut écraser r0. suis l'évolution sur un debugger, type insight et tu verra qu'après l'instruction à l'adresse 00011010 tu as bien E89DA00 dans r0

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Je n'ai pas la reponse a la question originale, mais j'ai celle de Woods Barrack :

    R0 - R3 sont ce qu'on apelle des scratch register. C'est a dire que leur etat n'est pas garantis quand on apelle une fonction, c'est au code appelant de les sauvegarder si besoin est. Les autres registres sont a sauvegarder par le programme appelé s'il veux les utiliser.

    En mode debug, on veux souvent connaitre la pile d'appel. Le probleme est que quand R0-R3 se font scratcher, on ne peut pas savoir avec quel paramettres ont ete appelées les fonction precedentes, c'est pourquoi ils sont sauvegarder en debug. Simplement pour pouvoir connaitre simplement quel a ete appelé avec quel paramettre.

    Sinon, un sub sp, sp, #4 ne fait pas d'acces memoire. Or les latences memoires sont enomres en temps processeur, alors que cette instruction via pipeline ne met qu'un cycle a s'executer. C'est ideal si on est pas sur d'utiliser cette cellule memoire car on evite un acces memoire, qui peut prendre un sacré paquet de cycles (en fait cela depend du type de memoire a laquelle on a a faire).

Discussions similaires

  1. Appel d'une fonction dans une fonction d'une même classe
    Par script73 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 10h18
  2. Réponses: 6
    Dernier message: 02/11/2011, 09h34
  3. 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
  4. Appel d'une fonction dans une fonction (sql server 2005)
    Par catchouse dans le forum Développement
    Réponses: 10
    Dernier message: 06/05/2009, 12h03
  5. Appeler une fonction dans une fonction
    Par bryanstaubin dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 18/06/2007, 09h39

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