Pergunta

Ao incorporar montagem código em um programa C / C ++, você pode evitar sobrepor registros salvando-os com uma instrução push (ou especificar lista clobber de suportes compilador TI).

Se você estiver incluindo montagem em linha e quer evitar a sobrecarga de empurrar e popping registros derrotado, há uma maneira de deixá-gcc escolher registros achados para você (por exemplo, aqueles que sabem não têm informação útil neles).

Foi útil?

Solução

Sim. Você pode especificar que deseja uma determinada variável (entrada ou saída) a ser armazenado em um registro, mas você não tem que especificar um registo. Consulte este documento para uma explicação detalhada. Essencialmente, a linha de montagem se parece com isso:

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

Outras dicas

Compiler intrínsecos são uma maneira muito útil para misturar montagem e de código C / C ++. Eles são declarações que parecem funções, mas na verdade compilar diretamente para instruções nativas individuais (via um caso especial dentro do compilador). Isto dá-lhe a maior parte do controle de trabalhar em conjunto, mas deixa o registo coloração e agendamento até o compilador.

Uma vantagem é que, em seguida, você pode passar uma variável C ordinário em um intrínseco, e deixar o compilador cuidar de carregá-lo para o registo e agendamento de outros ops em torno dele. Por exemplo,

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, então eu não pode deixar um comentário acima, mas eu tenho certeza que a sintaxe correta (diferente da mostrada acima) é:

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

Embora você pode deixar a alocação de registros de entrada e saída para o compilador, não há nenhuma maneira óbvia de deixar a alocação de registradores scratch / Temp (ou seja usada para valores intermediários, mas não uma entrada ou saída) para o compilador. Historicamente, eu apenas listados-los explicitamente na lista clobber (por exemplo, "% XMM1", "% rcx"), mas agora eu acho que pode ser melhor para incluí-los como saídas, a fim de permitir que o compilador para escolhê-los. Eu não sei de qualquer fonte que resolve este problema definitivamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top