Si vous souhaitez appeler une fonction C / C ++ à partir de l'assemblage en ligne, vous pouvez faire quelque chose comme ceci:
call callee
4 Réponses :
L'astuce est la concaténation littérale à chaîne. Avant que GCC ne commence à essayer d'obtenir une signification réelle de votre code, il concaténera des littéraux stricts adjacents, alors même si les cordes d'assemblage ne sont pas identiques que les autres chaînes que vous utilisez dans votre programme, elles devraient être concaténées si vous le faites:
#define ASM_CALL(X) asm("\t call " #X "\n") int main(void) { ASM_CALL(my_function); return 0; }
Non, cela ne fonctionne pas du tout. Premièrement, le «$» est totalement erroné pour appeler, second qu'il ne veut pas «my_function» dans la chaîne ASM, mais le nom Mangelé que C ++ génère B>.
Je n'ai pas vu que c'était aussi pour C ++. Dans ce cas, il est probable que cela ne fonctionnera pas si le nom de la fonction est surchargé sans beaucoup de cerceaux. Je viens de copier le "$" d'un autre poste depuis que je ne me suis pas souvenu de la main de la main X86 ASM. Fixer ça ...
J'ai eu le Réponse du mailing de GCC Liste: maintenant, je dois juste savoir ce que Pour que cela soit sûr, vous devez indiquer au compilateur à propos de tous les registres que l'appel de la fonction pourrait modifier, par exemple. % p0 code> signifie en réalité parce qu'il semble être une fonctionnalité non documentée ... P>
p code> devant un moyen de contrainte. Mais, entre autres choses, il empêche la GCC de mettre un
$ code> devant des valeurs constantes. Ce dont j'ai besoin dans ce cas. P>
: "EXA", "ECX", "EDX", "XMM0", "XMM1", ..., "st (0)" "," st (1) ", ... code>. P>
Voir aussi Stackoverflow.com/questions / 37639993 / ... pour Les dangers de l'utilisation de appelle code> de Inline ASM B>. Il est essentiellement impossible de faire de manière fiable pour X86-64 System V (Linux), car vous ne pouvez pas dire au compilateur que vous souhaitez clocer la zone rouge. C'est généralement une mauvaise idée. Voir Stackoverflow.com/Questions/ 7984209 / ... .
@Petercordes Cela semble être la question la plus susceptible de «Comment faire de l'appel de la fonction d'assemblée en ligne», je vous recommande de centraliser la réponse des pièges ici.
@Cirosantilli 疆疆 中心 996icu 六四 六四: Peut-être une modification de cette réponse pour inclure un avertissement de grosse graisse et des liens vers plus de détails serait approprié. Et d'inclure un "mémoire" code> clobber sauf si la fonction que vous appelez est connue de ne pas avoir d'effets secondaires visibles à cette fonction.
@Petercordes qui aiderait. Ma réponse préférée jusqu'à présent est la tentative de béton de Michael: Stackoverflow.com/Questtions/37502841/...
Et BTW, mise à jour: % p code> est documenté maintenant, pour imprimer des noms de symboles sans décoration. Ou d'imprimer
foo @ plt code> si nécessaire / approprié. gcc.gnu.org/onlinedocs/gcc/... < / a>
Si vous générez du code 32 bits (option E.G. -M32 GCC), l'ASM suivant en ligne émet un appel direct:
asm ("call %0" :: "m" (callee));
Peut-être que je manque quelque chose ici, mais devrait fonctionner correctement. Vous avez besoin d'externe "c" afin que le nom ne soit pas décoré en fonction des règles de mangling nommant C ++. P> p>
Êtes-vous sûr que l'appel indirect détruit le pipeline? Avez-vous aspiré? Ma compréhension était que dans les vieux jours de X86 (avant I686), des appels indirects étaient très mauvais (je me souviens d'être un bon 10-100 fois plus lent sur ma K6), mais de nos jours, les processeurs sont plus intelligents et peuvent les traiter tout simplement bien. . Alors, certains tests avant de passer aux conclusions!
@R ..: Vous avez raison: si je comparais ceci sur un vrai processeur, cela ne fait aucune différence. Je gère mon code à Qemu, cependant, et il semble faire une différence là-bas (environ 20% de plus de cycles / appel).
Ensuite, je voudrais juste rester avec la façon dont vous le faites, avec l'appel indirect. Cela permettra à GCC de générer le code correct pour les bibliothèques / exécutables Pic / Pie sans avoir à insérer des hacks spéciaux pour gérer ces choses.
@R ..: oui ce serait probablement la meilleure idée. Bien que je n'ai pas à vous inquiéter de pic / pie (c'est le code du noyau), je suis donc toujours intéressé à trouver une bonne solution à ce problème.
Eh bien, si c'est le code du noyau, il suffit de coder l'appel et de mettre
__ attribut __ ((utilisé)) code> sur la fonction afin que cela ne soit pas optimisé. Vous n'avez pas à vous soucier de la portabilité si vous avez une architecture unique OS et CPU. Au fait, utilisez-vous vraiment C ++ dans le code du noyau ??
@R ..: Oui C'est probablement la meilleure option bien que je n'aime pas avoir à coder de manière difficile le nom mutilé ... et oui, j'utilise vraiment C ++ :-) Ce n'est qu'un noyau de passe-temps, cependant.