Uso e preservação de registros de Assembly embutido
Específicos do Microsoft
Em geral, você não deve supor que um registro terá um determinado valor quando um __asm bloco começa.Não há garantia de valores do registro para ser preservadas em separado __asm blocos.Se você finalizar um bloco de código embutido e começa outra, você não pode contar com os registradores no segundo bloco para manter seus valores do primeiro bloco.Um __asm herda de bloco que registrar o resultado de valores do fluxo normal de controle.
Se você usar o __fastcall convenção de chamada, o compilador passa argumentos da função nos registradores em vez de na pilha.Isso pode criar problemas em funções com __asm bloqueia porque uma função não tem como saber qual parâmetro está na qual o registro.Se a função acontece receber um parâmetro em EAX e imediatamente armazena algo em EAX, o parâmetro original é perdido.Além disso, você deve preservar o registrador ecx em qualquer função declarada com __fastcall.
Para evitar tais conflitos de registro, não use o __fastcall convenção para funções que contêm um __asm bloco.Se você especificar o __fastcall convenção globalmente com a opção de compilador /Gr, declarar a cada função que contém um __asm bloquear com __cdecl ou __stdcall.(O __cdecl atributo informa o compilador para usar a convenção de chamada c para essa função.) Se você não está compilando com /Gr, evitar declarar a função com o __fastcall atributo.
Ao usar o __asm para escrever a linguagem assembly em funções de C/C++, você não precisa preservar os registradores EAX, EBX, ECX, EDX, ESI ou EDI.Por exemplo, no POWER2.Exemplo de c Funções de escrita com Assembly embutido, o power2 função não preserva o valor no registro EAX.Entretanto, usar esses registradores afetará a qualidade de código porque o alocador de registro não pode usar para armazenar valores em __asm blocos.Além disso, usando EBX, ESI ou EDI no código de assembly embutido, forçar o compilador para salvar e restaurar esses registradores no prólogo de função e epílogo.
Você deve preservar outros registros que você usar (como o DS, SS, SP, BP e registradores sinalizadores) para o escopo do __asm bloco.Você deve preservar os registradores de ESP e EBP, a menos que você tem alguma razão para alterá-los (para alternar a pilhas, por exemplo).Consulte também Otimização Assembly de in-line.
Alguns tipos de SSE requerem o alinhamento da pilha de oito bytes, forçando o compilador emita código dinâmico de alinhamento de pilha.Para poder acessar as variáveis locais e os parâmetros da função após o alinhamento, o compilador mantém dois ponteiros do quadro.Se o compilador executa a omissão de ponteiro do quadro (FPO), ele usará EBP e ESP.Se o compilador não executar FPO, ele usará EBX e EBP.Para garantir que o código é executado corretamente, não modifique EBX no código do asm se a função requer o alinhamento de pilha dinâmico como ele poderia modificar o ponteiro do quadro.Mova os tipos de alinhamento de oito bytes da função, ou evitar o uso de EBX.
Observação |
---|
Se o seu código de assembly embutido mudar o sinalizador de direção usando as instruções STD, ou CLD, você deve restaurar o sinalizador para seu valor original. |
Específicos do Microsoft final