Comment appeler des fonctions C de BRAS de Montage?
Je suis en train d'écrire le code de ciblage ARM Cortex-Un sur les appareils Android (à l'aide d'assembleur GNU et le compilateur), et je suis en train de faire l'interface entre l'Assemblée et de C. En particulier, je suis intéressé par l'appel de fonctions écrites en C de l'Assemblée. J'ai essayé beaucoup de choses, y compris la .extern
directive, à déclarer des fonctions C avec asm
et __asm__
et ainsi de suite, mais aucun d'entre eux travaillaient, donc je suis à la recherche d'un exemple minimal de le faire. Une référence à un tel exemple serait aussi bienvenu.
Je pensais à ça, mais C utilise les fichiers d'en-tête avec les déclarations de fonction pour la communication entre les différents fichiers. Ne serait-il pas une image complètement différente?
Le compilateur recherche à la déclaration de la fonction dans le fichier d'en-tête pour compiler l'appel. Vous aurez besoin de faire la même manuellement.
Le compilateur recherche à la déclaration de la fonction dans le fichier d'en-tête pour compiler l'appel. Vous aurez besoin de faire la même manuellement.
OriginalL'auteur Phonon | 2011-12-07
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin de lire le BRAS de BRAS et/ou connaissez le jeu d'instructions est tout, normalement, vous voulez faire quelque chose comme ceci
Vous pouvez essayer vous-même. pour gnu comme et gcc cela fonctionne bien il devrait également fonctionner très bien si vous utilisez clang pour obtenir le code c d'un objet et de gnu, comme pour l'assembleur. Pas sûr de ce que vous êtes en utilisant.
Le problème ci-dessus est la bl a une portée limitée,
sachant que le bl instruction définit le lien s'inscrire à l'instruction après le bl enseignement, alors si vous lisez sur le registre compteur de programme:
donc, si vous faites vos asm ressembler à ceci:
vous obtenez
Le monteur réserve un emplacement de la mémoire, à la portée de la ldr pc, instruction (si possible, sinon de générer une erreur) où il place les 32 bits de l'adresse de l'instruction. l'éditeur de liens par la suite de remplir cette adresse avec l'adresse externe. de cette façon, vous pouvez atteindre n'importe quelle adresse dans l'espace d'adressage.
si vous ne voulez pas jouer assembleur jeux comme ça et que vous voulez être en contrôle, alors vous créez l'emplacement de garder l'adresse de la fonction et de la charger dans le pc vous-même:
compilé:
Enfin, si vous souhaitez déplacer dans le moderne ARM monde où les BRAS et le pouce est mixte ou peut être (par exemple l'utilisation bx lr au lieu de mov pc,lr), alors vous voudrez utiliser bx
bien sûr, vous avez besoin d'un autre registre pour le faire et n'oubliez pas de push et pop votre lien de registre et l'autre registre avant et après votre appel à C si vous souhaitez les conserver.
et vous avez raison, j'ai seulement montré le comment avoir des BRAS instructions d'appeler une fonction de ne pas avoir de pouce instructions d'appeler une fonction C que je peut modifier la réponse et vous montrer comment le faire bien...vous avez parlé d'un cortex d'Un donc je suppose que vous êtes de bras exécutant des instructions de pouce pour la plupart, en tirant parti de la puissance que vous avez et ce n'est pas quelques bus contraint chose.
Et comme Brett mentionné transférable, les objets peuvent rendre les choses plus compliquées, vous auriez besoin de faire cfun_addr mondiale, et qui charge le transférable, l'objet doit modifier cfun_addr avant de l'utiliser.
Le Respect old_timer!
OriginalL'auteur old_timer
Vous avez besoin le cahier des charges pour la
armeabi-v7a
, décrivant la pile d'appel, les registres (le destinataire de l'appel contre l'appelant), etc. Ensuite, regardez assemblée de sortie de compilé en code C pour la syntaxe, etc. Les choses sont plus complexes lorsque vous essayez d'appeler des fonctions dans les bibliothèques partagées ou transportables destinés à des objets.OriginalL'auteur Brett Hale
Minimum praticable armv7 exemple
Cette question revient "qu'est-ce que le BRAS de convention d'appel (VAMP)". Un exemple
a.S
:Puis sur Ubuntu 16.04:
De sortie:
Le plus simple erreur d'en faire dans les cas les plus complexes, c'est oublier que la pile doit être de 8 octets aligné. E. g., vous souhaitez:
au lieu de:
Exemple sur GitHub avec le standard généralisé: https://github.com/cirosantilli/arm-assembly-cheat/blob/82e915e1dfaebb80683a4fd7bba57b0aa99fda7f/c_from_arm.S
C
fonction.n'est-ce pas
puts
une fonction C? 🙂OriginalL'auteur Ciro Santilli 新疆改造中心 六四事件 法轮功
Comme Brett dit, tout ce que vous avez à faire est de mettre les bonnes valeurs dans le droit des registres, et de la direction générale-avec-link à l'adresse de la fonction. Vous aurez besoin d'être conscient de ce registre de la fonction compilée va l'écraser, et qui les registres, il permettra de restaurer avant qu'il ne retourne-c'est tout écrit dans l'ABI de la documentation à infocentre.arm.com. Vous aurez également besoin de vous assurer que la pile de registre est définie à ce que le compilateur s'attend, et peut-être d'autres registres (le PIC de mode?)
Mais, avez-vous vraiment besoin d'écrire le code en assembleur fichiers?
Si vous utilisez GCC "asm", vous pouvez intégrer assembler des fragments (aussi longtemps que vous le souhaitez) dans des fonctions C, et de retour dans C à chaque fois que c'est plus pratique.
Il y a des cas où le fait d'avoir C gubbins autour ne le fera pas, mais si vous pouvez appeler des fonctions C je devine que vous n'êtes pas dans ceux.
Pourquoi avez-vous besoin d'utiliser de l'assembleur .... C est fondamentalement de haut niveau assembleur de toute façon?
OriginalL'auteur ams