Passagem de parâmetro
Os argumentos de quatro inteiro primeiro serão passados nos registradores. Valores inteiros serão passados no RCX, RDX, R8 e R9 (na ordem da esquerda para a direita). Quatro de argumentos e superior, será passado para a pilha. Todos os argumentos são justificados à direita em registros. Isso é feito para que o receptor pode ignorar os bits superiores do registro se necessário e pode acessar somente a parte do Registro necessárias.
Ponto flutuante e precisão dupla de argumentos são passados em XMM0 – XMM3 (até 4) com o slot de inteiro (RCX, RDX, R8 e R9) que normalmente seria utilizado para o slot cardinais sendo ignorada (veja exemplo) e vice-versa.
__m128tipos, matrizes e strings nunca são passados por valor imediato, mas em vez disso, um ponteiro será passado para a memória alocada pelo chamador. Estruturas/uniões de tamanho 8, 16, 32 ou 64 bits de e __m64 serão passados como se fossem inteiros do mesmo tamanho. Estruturas/uniões diferente, por exemplo, esses tamanhos serão passados como um ponteiro para a memória alocada pelo chamador. Para esses tipos de agregados passados como um ponteiro (incluindo __m128), a memória temporária alocada para chamador será alinhado de 16 bytes.
Funções intrínsecas que não pode alocar espaço de pilha e não chamam outras funções podem usar outros registradores volátil para passar os argumentos adicionais de registro porque há uma forte ligação entre o compilador e a implementação da função intrínseca. Esta é uma oportunidade adicional para melhorar o desempenho.
O receptor tem a responsabilidade de despejar os parâmetros de registro no seu espaço de sombra, se necessário.
A tabela a seguir resume como os parâmetros são passados:
Tipo de parâmetro |
Como passada |
---|---|
Floating point |
Primeiro 4 parâmetros – XMM0 por meio de XMM3. Outros passaram na pilha. |
Integer |
Primeiro 4 parâmetros – RCX, RDX, R8, R9. Outros passaram na pilha. |
Agregações (8, 16, 32 ou 64 bits) e __m64 |
Primeiro 4 parâmetros – RCX, RDX, R8, R9. Outros passaram na pilha. |
Agregações (outros) |
Pelo ponteiro. Primeiro, 4 parâmetros passados como ponteiros de RCX, RDX, R8 e R9 |
__m128 |
Pelo ponteiro. Primeiro, 4 parâmetros passados como ponteiros de RCX, RDX, R8 e R9 |
Exemplo de argumento passando 1 – todos os inteiros
func1(int a, int b, int c, int d, int e);
// a in RCX, b in RDX, c in R8, d in R9, e pushed on stack
Exemplo de argumento passando 2 – todos os floats
func2(float a, double b, float c, double d, float e);
// a in XMM0, b in XMM1, c in XMM2, d in XMM3, e pushed on stack
Exemplo de argumento passando 3 – icas mistas e floats
func3(int a, double b, int c, float d);
// a in RCX, b in XMM1, c in R8, d in XMM3
Exemplo de argumento passando 4 –__m64, __m128 e agregados
func4(__m64 a, _m128 b, struct c, float d);
// a in RCX, ptr to b in RDX, ptr to c in R8, d in XMM3