2016-12-18 2 views
5

Je sais que le compilateur MSVC en mode x64 ne supporte pas les extraits de code en ligne, et pour utiliser le code d'assembly, vous devez définir votre fonction dans un fichier my_asm_funcs.asm externe comme ça :Rendre la fonction d'assemblage inline dans Visual Studio

my_asm_func PROC 
    mov rax, rcx 
    ret 
my_asm_func ENDP 

et puis dans votre .c ou .h vous définissez un en-tête de la fonction comme ça:

int my_asm_func(int x); 

Bien que cette solution répond à de nombreuses préoccupations, mais je suis toujours intéressé à faire que fonction de code d'assemblage pour être en ligne, en d'autres termes - après com pilation Je ne veux pas d'appels à my_asm_func, je veux juste que ce morceau d'assemblage soit collé dans mon code compilé final. J'ai essayé de déclarer la fonction avec inline et __forceinline mots-clés, mais rien ne semble aider. Y a-t-il encore un moyen de faire ce que je veux?

+2

Avez-vous cherché dans les intrinsèques du compilateur? C'est peut-être la chance, qu'il y a quelque chose, qui couvre la fonctionnalité de 'my_asm_func'. En général, mélanger votre propre assemblage en ligne avec un compilateur qui fait beaucoup d'optimisations (selon le niveau d'optimisation) peut être difficile à faire fonctionner, sans parler de sa maintenance. –

+1

Non, impossible. Voir ce [répondre à une question similaire] (http://stackoverflow.com/a/5542379/597607) pour certaines raisons. –

Répondre

10

Non, il n'y a aucun moyen de faire ce que vous voulez.

Le compilateur de Microsoft ne prend pas en charge l'assemblage en ligne pour les cibles x86-64, comme vous l'avez dit. Cela vous oblige à définir vos fonctions d'assemblage dans un module de code externe (* .asm), à les assembler avec MASM et à lier le résultat avec votre code C/C++ compilé séparément. La séparation des étapes requise signifie que le compilateur C/C++ ne peut pas aligner vos fonctions d'assemblage car elles ne sont pas visibles au moment de la compilation.

Même avec la génération de code de liaison (LTCG) activée, vos modules d'assemblage ne seront pas insérés car l'éditeur de liens ne le supporte pas.

Il n'y a absolument aucun moyen d'écrire les fonctions d'assemblage dans un module séparé directement incorporé dans un code C ou C++.

Il n'y a aucun moyen que les inline ou __forceinline mots-clés pourraient faire quoi que ce soit. En fait, vous ne pouvez pas les utiliser sans une erreur de compilation (ou au moins un avertissement). Ces annotations doivent aller sur la définition de la fonction (qui, pour une fonction inline, est la même que sa déclaration), mais vous ne pouvez pas la mettre dans la définition de la fonction, car elle est définie dans un fichier * .asm distinct. Ce ne sont pas des mots-clés MASM, donc essayer de les ajouter à la définition entraînerait nécessairement une erreur. Et les mettre sur la déclaration directe de la fonction d'assemblage dans l'en-tête C va échouer de la même façon, puisqu'il n'y a pas de code pour l'intégrer - juste un prototype.

C'est pourquoi Microsoft recommande d'utiliser intrinsèques. Vous pouvez les utiliser directement dans votre code C ou C++, et le compilateur émettra le code d'assembly correspondant automatiquement. Non seulement cela permet d'obtenir l'inline souhaité, mais les intrinsèques permettent même à l'optimiseur de fonctionner, améliorant encore les résultats. Non, les intrinsèques ne conduisent pas à un code parfait, et il n'y a pas d'intrinsèque pour tout, mais c'est le meilleur que l'on puisse faire avec le compilateur de Microsoft. Votre seule autre alternative est de s'asseoir et de jouer avec diverses permutations de code C/C++ jusqu'à ce que le compilateur génère le code objet désiré.Cela peut être très puissant dans les cas où les instructions intrinsèques ne sont pas disponibles pour les instructions que vous souhaitez générer, mais cela prend beaucoup de temps à remuer, et vous devrez le revoir pour vous assurer qu'il continue à faire ce que vous voulez. voulez quand vous mettez à jour les versions du compilateur.