Question

Lors de l'intégration du code assembleur dans un C / C ++ programme, vous pouvez éviter les registres en les démolir sauver avec une instruction push (ou spécifier la liste des clobber du compilateur supporte).

Si vous incluez ligne d'assemblage et que vous voulez éviter les frais généraux de pousser et popping registres mis à mal, est-il un moyen de laisser gcc choisir des registres pour vous (par exemple ceux qu'il sait avoir aucune information utile pour eux).

Était-ce utile?

La solution

Oui. Vous pouvez spécifier que vous souhaitez une variable particulière (entrée ou sortie) à stocker dans un registre, mais vous ne devez pas spécifier un registre. Voir ce document pour une explication détaillée. Pour l'essentiel, l'assemblage en ligne ressemble à ceci:

asm("your assembly instructions"
      : output1("=a"),  // I want output1 in the eax register
        output2("=r"),  // output2 can be in any general-purpose register
        output3("=q"),  // output3 can be in eax, ebx, ecx, or edx
        output4("=A")   // output4 can be in eax or edx
      : /* inputs */
      : /* clobbered registers */
   );

Autres conseils

compilateur sont intrinsics un moyen très utile pour l'assemblage et le code C / C ++ mélanger. Ils sont des déclarations qui ressemblent à des fonctions, mais compilent en fait directement aux instructions natives individuelles (par un cas particulier à l'intérieur du compilateur). Cela vous donne une grande partie du contrôle du travail dans l'ensemble, mais laisse le registre coloration et la planification jusqu'à compilateur.

Un avantage est que vous pouvez passer une variable ordinaire C en un intrinsèque, et laisser le compilateur prendre soin de le charger sur le registre et la planification d'autres opérations autour. Par exemple,

struct TwoVectors
{
   __m128 a; __m128b;
}

// adds two vectors A += B using the native SSE opcode
inline void SimdADD( TwoVectors *v ) 
{
   v->a = _mm_add_ps( v->a , v->b ); // compiles directly to ADDSS opcode
}

OK, donc je ne peux pas laisser un commentaire ci-dessus, mais je suis sûr que la syntaxe correcte (différente de celle indiquée ci-dessus) est:

asm ( "your assembly instructions"
    : "=a"(output1),
      "=r"(output2),
      "=q"(output3),
      "=A"(output4)
    : /* inputs */
    : /* clobbered registers */
);

Bien que vous pouvez laisser l'attribution des registres d'entrée et de sortie au compilateur, il n'y a pas de façon évidente de laisser l'attribution de registres zéro / temp (à savoir utilisé pour les valeurs intermédiaires, mais pas une entrée ou sortie) au compilateur. Par le passé, je les explicitement détaillés dans la liste des clobber (par exemple « % XMM1 », « % rcx »), mais je pense que maintenant il pourrait être préférable de les énumérer comme sorties afin de permettre au compilateur de les choisir. Je ne sais pas d'une source qui traite cette question définitivement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top