Paso de parámetros
Actualización: noviembre 2007
Los cuatro primeros argumentos de tipo entero se pasan en registros. Los valores enteros se pasan (en orden de izquierda a derecha) en RCX, RDX, R8 y R9. Los argumentos cuarto y posteriores se pasan a la pila. Todos los argumentos tienen justificación a la derecha en los registros. De este modo, el destinatario puede omitir los bits superiores del registro si es necesario y tiene acceso únicamente a la parte del registro que necesita.
Los argumentos de punto flotante y de precisión doble se pasan en XMM0 a XMM3 (hasta 4), con la ranura para enteros (RCX, RDX, R8 y R9) que se utilizaría normalmente para que se omitirse la ranura para cardinales (vea el ejemplo) y viceversa.
Las matrices, las cadenas y los tipos de __m128 nunca se pasan mediante un valor inmediato, sino que se pasa un puntero a la memoria asignada por el llamador. Las estructuras y las uniones de tamaño 8, 16, 32 ó 64 bits y __m64 se pasan como si fueran enteros del mismo tamaño. Las estructuras y las uniones de tamaños distintos a estos se pasan como un puntero a la memoria asignada por el llamador. Para estos tipos agregados pasados como un puntero (incluso __m128), la memoria temporal asignada por el llamador tendrá alineación de 16 bytes.
Las funciones intrínsecas que no asignan espacio de la pila y no llaman a otras funciones pueden usar otros registros variables para pasar argumentos de registro adicionales, ya que hay una estrecha relación entre el compilador y la implementación de la función intrínseca. Esta es una oportunidad más para mejorar el rendimiento.
El destinatario tiene la responsabilidad de volcar los parámetros de registro en su espacio central si es necesario.
La tabla siguiente resume cómo se pasan los parámetros:
Tipo de parámetro |
Cómo se pasa |
---|---|
Punto flotante |
4 primeros parámetros - XMM0 a XMM3. Otros se pasan en la pila. |
Integer |
4 primeros parámetros - RCX, RDX, R8, R9. Otros se pasan en la pila. |
Agregados (8, 16, 32 ó 64 bits) y __m64 |
4 primeros parámetros - RCX, RDX, R8, R9. Otros se pasan en la pila. |
Agregados (otros) |
Mediante puntero. 4 primeros parámetros pasados como punteros en RCX, RDX, R8 y R9 |
__m128 |
Mediante puntero. 4 primeros parámetros pasados como punteros en RCX, RDX, R8 y R9 |
Ejemplo de paso de argumentos 1 - todos los enteros
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
Ejemplo de paso de argumentos 2 - todos los flotantes
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
Ejemplo de paso de argumentos 3 - enteros y flotantes combinados
func3(int a, double b, int c, float d);
// a in RCX, b in XMM1, c in R8, d in XMM3
Ejemplo de paso de argumentos 4 - __m64, __m128 y 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