Pregunta

Cuando la incrustación de código ensamblador en un programa en C / C ++, puede evitar registros clobbering guardándolos con una instrucción de empuje (o especificar la lista de clobber compilador soporta).

Si va a incluir en línea de montaje y quiere evitar la sobrecarga de empujar y hacer estallar los registros Demolí, hay una manera de dejar que gcc elegir registros para usted (por ejemplo, los que sabe que hay información útil en ellos).

¿Fue útil?

Solución

Sí. Puede especificar que desea una determinada variable (entrada o salida) para ser almacenado en un registro, pero no tiene que especificar un registro. Ver este documento para una explicación detallada. En esencia, el ensamblador en línea es el siguiente:

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 */
   );

Otros consejos

intrínsecos del compilador son una forma muy útil montaje y / C código C ++ mezclar. Son declaraciones que se parecen a las funciones, pero en realidad compilan directamente a las instrucciones nativas individuales (a través de un caso especial dentro del compilador). Esto le da gran parte del control del trabajo en el montaje, pero deja el registro de la coloración y la programación hasta el compilador.

Una de las ventajas es que entonces puede pasar de una variable C ordinaria en una intrínseco, y dejar que el compilador de cuidar de cargarlo en el registro y la programación de otras operaciones alrededor de ella. Por ejemplo,

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, así que no puedo dejar un comentario anterior, pero estoy bastante seguro de que la sintaxis correcta (diferente de la que se muestra arriba) es:

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

A pesar de que se puede salir de la asignación de los registros de entrada y salida para el compilador, no hay manera obvia de salir de la asignación de los registros cero / temp (es decir, se utiliza para los valores intermedios, pero no una entrada o salida) para el compilador. Históricamente, acabo de ellas expresamente enumerados en la lista clobber (por ejemplo, "% XMM1", "% rcx"), pero ahora creo que puede ser mejor para enumerarlos como salidas con el fin de permitir que el compilador para elegirlos. No sé de cualquier fuente que soluciona este problema definitivamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top