Convenciones de software x64x64 software conventions

En esta sección se describe la metodología de convención de llamada de C++ para x64, la extensión de 64 bits de la arquitectura x86.This section describes the C++ calling convention methodology for x64, the 64-bit extension to the x86 architecture.

Información general sobre las convenciones de llamada de x64Overview of x64 calling conventions

Dos diferencias importantes entre x86 y x64 son la capacidad de direccionamiento de 64 bits y un conjunto plano de 16 registros de 64 bits para uso general.Two important differences between x86 and x64 are the 64-bit addressing capability and a flat set of 16 64-bit registers for general use. Dado el conjunto de registros expandido, x64 usa la convención de llamada __fastcall y un modelo de control de excepciones basado en RISC.Given the expanded register set, x64 uses the __fastcall calling convention and a RISC-based exception-handling model. La convención __fastcall usa registros para los primeros cuatro argumentos y el marco de pila para pasar argumentos adicionales.The __fastcall convention uses registers for the first four arguments and the stack frame to pass additional arguments. Para obtener información detallada sobre la convención de llamada de x64, incluido el uso de registros, parámetros de la pila, valores devueltos y el desenredado de la pila, vea Convención de llamada de x64.For details on the x64 calling convention, including register usage, stack parameters, return values, and stack unwinding, see x64 calling convention.

Habilitación de la optimización para x64Enable optimization for x64

La siguiente opción del compilador le ayuda a optimizar la aplicación para x64:The following compiler option helps you optimize your application for x64:

Tipos y almacenamientoTypes and storage

En esta sección se describe la enumeración y el almacenamiento de tipos de datos para la arquitectura x64.This section describes the enumeration and storage of data types for the x64 architecture.

Tipos escalaresScalar types

Aunque es posible acceder a los datos con cualquier alineación, se recomienda alinearlos en su límite natural, o por algún múltiplo, para evitar la pérdida de rendimiento.Although it's possible to access data with any alignment, it's recommended to align data on its natural boundary, or some multiple, to avoid performance loss. Las enumeraciones son enteros constantes y se tratan como enteros de 32 bits.Enums are constant integers and are treated as 32-bit integers. En la tabla siguiente se describe la definición de tipo y el almacenamiento recomendado para los datos con relación a la alineación mediante los valores de alineación siguientes:The following table describes the type definition and recommended storage for data as it pertains to alignment using the following alignment values:

  • Byte: 8 bitsByte - 8 bits

  • Palabra: 16 bitsWord - 16 bits

  • Doble palabra: 32 bitsDoubleword - 32 bits

  • Palabra cuádruple: 64 bitsQuadword - 64 bits

  • Doble palabra cuádruple: 128 bitsOctaword - 128 bits

Tipo escalarScalar Type Tipo de datos de CC Data Type Tamaño de almacenamiento (en bytes)Storage Size (in bytes) Alineación recomendadaRecommended Alignment
INT8 char 11 ByteByte
UINT8 unsigned char 11 ByteByte
INT16 short 22 PalabraWord
UINT16 unsigned short 22 PalabraWord
INT32 int, longint, long 44 Doble palabraDoubleword
UINT32 unsigned int, unsigned longunsigned int, unsigned long 44 Doble palabraDoubleword
INT64 __int64 88 Palabra cuádrupleQuadword
UINT64 unsigned __int64 88 Palabra cuádrupleQuadword
FP32 (precisión sencilla)FP32 (single precision) float 44 Doble palabraDoubleword
FP64 (precisión doble)FP64 (double precision) double 88 Palabra cuádrupleQuadword
POINTER * 88 Palabra cuádrupleQuadword
__m64 struct __m64 88 Palabra cuádrupleQuadword
__m128 struct __m128 1616 Doble palabra cuádrupleOctaword

Agregados y unionesAggregates and unions

Otros tipos, como las matrices, estructuras y uniones, tienen requisitos de alineación más estrictos que garantizan el almacenamiento y la recuperación de datos coherentes de los agregados y las uniones.Other types, such as arrays, structs, and unions, have stricter alignment requirements that ensure consistent aggregate and union storage and data retrieval. Estas son las definiciones de matriz, estructura y unión:Here are the definitions for array, structure, and union:

  • MatrizArray

    Contiene un grupo ordenado de objetos de datos adyacentes.Contains an ordered group of adjacent data objects. Cada objeto se denomina elemento.Each object is called an element. Todos los elementos de una matriz tienen el mismo tamaño y tipo de datos.All elements within an array have the same size and data type.

  • EstructuraStructure

    Contiene un grupo ordenado de objetos de datos.Contains an ordered group of data objects. A diferencia de los elementos de una matriz, los objetos de datos de una estructura pueden tener distintos tamaños y tipos de datos.Unlike the elements of an array, the data objects within a structure can have different data types and sizes. Cada objeto de datos de una estructura se denomina miembro.Each data object in a structure is called a member.

  • UniónUnion

    Objeto que contiene cualquiera de un conjunto de miembros con nombre.An object that holds any one of a set of named members. Los miembros del conjunto con nombre pueden ser de cualquier tipo.The members of the named set can be of any type. El almacenamiento asignado para una unión es igual al almacenamiento necesario para el miembro más grande de esa unión, además de cualquier relleno necesario para la alineación.The storage allocated for a union is equal to the storage required for the largest member of that union, plus any padding required for alignment.

En la tabla siguiente se muestra la alineación recomendada para los miembros escalares de uniones y estructuras.The following table shows the strongly suggested alignment for the scalar members of unions and structures.

Tipo escalarScalar Type Tipo de datos de CC Data Type Alineación necesariaRequired Alignment
INT8 char ByteByte
UINT8 unsigned char ByteByte
INT16 short WordWord
UINT16 unsigned short WordWord
INT32 int, longint, long Doble palabraDoubleword
UINT32 unsigned int, unsigned longunsigned int, unsigned long Doble palabraDoubleword
INT64 __int64 Palabra cuádrupleQuadword
UINT64 unsigned __int64 Palabra cuádrupleQuadword
FP32 (precisión sencilla)FP32 (single precision) float Doble palabraDoubleword
FP64 (precisión doble)FP64 (double precision) double Palabra cuádrupleQuadword
POINTER * Palabra cuádrupleQuadword
__m64 struct __m64 Palabra cuádrupleQuadword
__m128 struct __m128 Doble palabra cuádrupleOctaword

Se aplican las siguientes reglas de alineación de agregados:The following aggregate alignment rules apply:

  • La alineación de una matriz es la misma que la alineación de uno de los elementos de la matriz.The alignment of an array is the same as the alignment of one of the elements of the array.

  • La alineación del inicio de una estructura o una unión es la alineación máxima de cualquier miembro individual.The alignment of the beginning of a structure or a union is the maximum alignment of any individual member. Cada miembro de la estructura o unión se debe colocar en su alineación adecuada, como se ha definido en la tabla anterior, lo que puede requerir un relleno interno implícito, en función del miembro anterior.Each member within the structure or union must be placed at its proper alignment as defined in the previous table, which may require implicit internal padding, depending on the previous member.

  • El tamaño de la estructura debe ser un múltiplo entero de su alineación, lo que puede requerir relleno después del último miembro.Structure size must be an integral multiple of its alignment, which may require padding after the last member. Como las estructuras y las uniones se pueden agrupar en matrices, cada elemento de matriz de una estructura o unión debe comenzar y finalizar en la alineación adecuada determinada antes.Since structures and unions can be grouped in arrays, each array element of a structure or union must begin and end at the proper alignment previously determined.

  • Es posible alinear los datos de tal forma que sean mayores que los requisitos de alineación, siempre y cuando se mantengan las reglas anteriores.It is possible to align data in such a way as to be greater than the alignment requirements as long as the previous rules are maintained.

  • Un compilador individual puede ajustar el empaquetado de una estructura por motivos de tamaño.An individual compiler may adjust the packing of a structure for size reasons. Por ejemplo, /Zp (alineación de miembros de estructura) permite ajustar el empaquetado de estructuras.For example /Zp (Struct Member Alignment) allows for adjusting the packing of structures.

Ejemplos de alineación de estructurasExamples of Structure Alignment

En los cuatro ejemplos siguientes se declara una estructura alineada o una unión, y en las figuras correspondientes se muestra el diseño de esa estructura o unión en la memoria.The following four examples each declare an aligned structure or union, and the corresponding figures illustrate the layout of that structure or union in memory. Cada columna de una ilustración representa un byte de memoria, y el número de la columna indica el desplazamiento de ese byte.Each column in a figure represents a byte of memory, and the number in the column indicates the displacement of that byte. El nombre de la segunda fila de cada ilustración se corresponde con el nombre de una variable en la declaración.The name in the second row of each figure corresponds to the name of a variable in the declaration. Las columnas sombreadas indican el relleno necesario para lograr la alineación especificada.The shaded columns indicate padding that is required to achieve the specified alignment.

Ejemplo 1Example 1

// Total size = 2 bytes, alignment = 2 bytes (word).

_declspec(align(2)) struct {
    short a;      // +0; size = 2 bytes
}

Diseño de la estructura del ejemplo 1 de conversión de AMDAMD conversion example 1 structure layout

Ejemplo 2Example 2

// Total size = 24 bytes, alignment = 8 bytes (quadword).

_declspec(align(8)) struct {
    int a;       // +0; size = 4 bytes
    double b;    // +8; size = 8 bytes
    short c;     // +16; size = 2 bytes
}

Diseño de la estructura del ejemplo 2 de conversión de AMDAMD conversion example 2 structure layout

Ejemplo 3Example 3

// Total size = 12 bytes, alignment = 4 bytes (doubleword).

_declspec(align(4)) struct {
    char a;       // +0; size = 1 byte
    short b;      // +2; size = 2 bytes
    char c;       // +4; size = 1 byte
    int d;        // +8; size = 4 bytes
}

Diseño de la estructura del ejemplo 3 de conversión de AMDAMD conversion example 3 structure layout

Ejemplo 4Example 4

// Total size = 8 bytes, alignment = 8 bytes (quadword).

_declspec(align(8)) union {
    char *p;      // +0; size = 8 bytes
    short s;      // +0; size = 2 bytes
    long l;       // +0; size = 4 bytes
}

Diseño de la unión del ejemplo 4 de conversión de AMDAMD conversion example 4 union layout

Campos de bitsBitfields

Los campos de bits de estructura se limitan a 64 bits y pueden ser de tipo signed int, unsigned int, int64 o unsigned int64.Structure bit fields are limited to 64 bits and can be of type signed int, unsigned int, int64, or unsigned int64. Los campos de bits que cruzan el límite de tipos omiten bits para alinear el campo de bits con la alineación de tipos siguiente.Bit fields that cross the type boundary will skip bits to align the bitfield to the next type alignment. Por ejemplo, los campos de bits enteros no pueden cruzar un límite de 32 bits.For example, integer bitfields may not cross a 32-bit boundry.

Conflictos con el compilador de x86Conflicts with the x86 compiler

Los tipos de datos de más de 4 bytes no se alinean automáticamente en la pila cuando se usa el compilador de x86 para compilar una aplicación.Data types that are larger than 4 bytes are not automatically aligned on the stack when you use the x86 compiler to compile an application. Como la arquitectura del compilador de x86 es una pila alineada de 4 bytes, todo lo que sea mayor de 4 bytes, por ejemplo, un entero de 64 bits, no se puede alinear de forma automática a una dirección de 8 bytes.Because the architecture for the x86 compiler is a 4 byte aligned stack, anything larger than 4 bytes, for example, a 64-bit integer, cannot be automatically aligned to an 8-byte address.

Trabajar con datos sin alinear tiene dos implicaciones.Working with unaligned data has two implications.

  • Se puede tardar más en acceder a ubicaciones no alineadas de lo que se tarda en acceder a ubicaciones alineadas.It may take longer to access unaligned locations than it takes to access aligned locations.

  • Las ubicaciones no alineadas no se pueden usar en operaciones de bloqueo.Unaligned locations cannot be used in interlocked operations.

Si necesita una alineación más estricta, use __declspec(align(N)) en las declaraciones de variables.If you require more strict alignment, use __declspec(align(N)) on your variable declarations. Esto hace que el compilador alinee de forma dinámica la pila para cumplir con las especificaciones.This causes the compiler to dynamically align the stack to meet your specifications. Pero el ajuste dinámico de la pila en tiempo de ejecución puede ralentizar la ejecución de la aplicación.However, dynamically adjusting the stack at run time may cause slower execution of your application.

Uso de registrosRegister usage

La arquitectura x64 proporciona 16 registros generales (que se denominarán registros enteros a partir de ahora), así como otros 16 registros de XMM/YMM, disponibles para el uso de puntos flotantes.The x64 architecture provides for 16 general-purpose registers (hereafter referred to as integer registers) as well as 16 XMM/YMM registers available for floating-point use. Los registros volátiles son registros residuales que el llamador da por hecho que van a destruirse a lo largo de la llamada.Volatile registers are scratch registers presumed by the caller to be destroyed across a call. En cuanto a los registros no volátiles, es necesarios conservar sus valores a lo largo de la llamada de función, y el destinatario de la llamada debe guardarlos si se usan.Nonvolatile registers are required to retain their values across a function call and must be saved by the callee if used.

Volatilidad y conservación de los registrosRegister volatility and preservation

En la siguiente tabla se explica el uso de cada registro en las llamadas de función:The following table describes how each register is used across function calls:

RegistroRegister SituaciónStatus UsarUse
RAXRAX VolátilVolatile Registro de valor devueltoReturn value register
RCXRCX VolátilVolatile Primer argumento de enteroFirst integer argument
RDXRDX VolátilVolatile Segundo argumento de enteroSecond integer argument
R8R8 VolátilVolatile Tercer argumento de enteroThird integer argument
R9R9 VolátilVolatile Cuarto argumento de enteroFourth integer argument
R10:R11R10:R11 VolátilVolatile El llamador debe conservarlo según sea necesario; utilizado en instrucciones syscall/sysretMust be preserved as needed by caller; used in syscall/sysret instructions
R12:R15R12:R15 No volátilNonvolatile El destinatario de la llamada debe conservarloMust be preserved by callee
RDIRDI No volátilNonvolatile El destinatario de la llamada debe conservarloMust be preserved by callee
RSIRSI No volátilNonvolatile El destinatario de la llamada debe conservarloMust be preserved by callee
RBXRBX No volátilNonvolatile El destinatario de la llamada debe conservarloMust be preserved by callee
RBPRBP No volátilNonvolatile Se puede usar como un puntero de marco; el destinatario de la llamada debe conservarlo según sea necesarioMay be used as a frame pointer; must be preserved by callee
RSPRSP No volátilNonvolatile Puntero de pilaStack pointer
XMM0, YMM0XMM0, YMM0 VolátilVolatile Primer argumento de FP; primer argumento de tipo vectorial cuando se usa __vectorcallFirst FP argument; first vector-type argument when __vectorcall is used
XMM1, YMM1XMM1, YMM1 VolátilVolatile Segundo argumento de FP; segundo argumento de tipo vectorial cuando se usa __vectorcallSecond FP argument; second vector-type argument when __vectorcall is used
XMM2, YMM2XMM2, YMM2 VolátilVolatile Tercer argumento de FP; tercer argumento de tipo vectorial cuando se usa __vectorcallThird FP argument; third vector-type argument when __vectorcall is used
XMM3, YMM3XMM3, YMM3 VolátilVolatile Cuarto argumento de FP; cuarto argumento de tipo vectorial cuando se usa __vectorcallFourth FP argument; fourth vector-type argument when __vectorcall is used
XMM4, YMM4XMM4, YMM4 VolátilVolatile El llamador debe conservarlo según sea necesario; quinto argumento de tipo vectorial cuando se usa __vectorcallMust be preserved as needed by caller; fifth vector-type argument when __vectorcall is used
XMM5, YMM5XMM5, YMM5 VolátilVolatile El llamador debe conservarlo según sea necesario; sexto argumento de tipo vectorial cuando se usa __vectorcallMust be preserved as needed by caller; sixth vector-type argument when __vectorcall is used
XMM6:XMM15, YMM6:YMM15XMM6:XMM15, YMM6:YMM15 No volátil (XMM), volátil (mitad superior de YMM)Nonvolatile (XMM), Volatile (upper half of YMM) Lo debe conservar el destinatario.Must be preserved by callee. El llamador debe conservar los registros de YMM según sea necesario.YMM registers must be preserved as needed by caller.

En la salida y entrada de la función para las llamadas a la biblioteca en tiempo de ejecución de C y las llamadas del sistema de Windows, se espera que la marca de dirección del registro de marcas de CPU se borre.On function exit and on function entry to C Runtime Library calls and Windows system calls, the direction flag in the CPU flags register is expected to be cleared.

Uso de la pilaStack usage

Para obtener más información sobre la asignación de pila, la alineación, los tipos de función y los marcos de pila en x64, vea Uso de la pila de x64.For details on stack allocation, alignment, function types and stack frames on x64, see x64 stack usage.

Prólogo y epílogoProlog and epilog

Todas las funciones que asignan espacio de pila, llaman a otras funciones, guardan registros no volátiles o usan el control de excepciones deben tener un prólogo cuyos límites de dirección se describen en los datos de desenredado asociados a la entrada de la tabla de funciones correspondiente, así como epílogos en cada salida de una función.Every function that allocates stack space, calls other functions, saves nonvolatile registers, or uses exception handling must have a prolog whose address limits are described in the unwind data associated with the respective function table entry, and epilogs at each exit to a function. Para obtener más información sobre el código de prólogo y epílogo necesario en x64, vea Prólogo y epílogo de x64.For details on the required prolog and epilog code on x64, see x64 prolog and epilog.

Control de excepciones x64x64 exception handling

Para obtener información sobre las convenciones y estructuras de datos que se usan para implementar el control de excepciones estructurado y el comportamiento del control de excepciones de C++ en x64, vea Control de excepciones en x64.For information on the conventions and data structures used to implement structured exception handling and C++ exception handling behavior on the x64, see x64 exception handling.

Elementos intrínsecos y ensamblado en líneaIntrinsics and inline assembly

Una de las restricciones del compilador x64 es la falta de compatibilidad con el ensamblador en línea.One of the constraints for the x64 compiler is to have no inline assembler support. Esto significa que las funciones que no se pueden escribir en C o C++ se tienen que crear como subrutinas o como funciones intrínsecas admitidas por el compilador.This means that functions that cannot be written in C or C++ will either have to be written as subroutines or as intrinsic functions supported by the compiler. Algunas funciones son sensibles el rendimiento y otras no.Certain functions are performance sensitive while others are not. Las funciones sensibles al rendimiento se deben implementar como funciones intrínsecas.Performance-sensitive functions should be implemented as intrinsic functions.

Los elementos intrínsecos que admite el compilador se describen en Intrínsecos del compilador.The intrinsics supported by the compiler are described in Compiler Intrinsics.

Formato de imagenImage format

El formato de imagen ejecutable de x64 es PE32+.The x64 executable image format is PE32+. Las imágenes ejecutables (tanto DLL como EXE) están restringidas a un tamaño máximo de 2 gigabytes, por lo que se puede usar el direccionamiento relativo con un desplazamiento de 32 bits para tratar los datos de imagen estáticos.Executable images (both DLLs and EXEs) are restricted to a maximum size of 2 gigabytes, so relative addressing with a 32-bit displacement can be used to address static image data. Estos datos incluyen la tabla de direcciones de importación, las constantes de cadena y los datos globales estáticos, entre otros.This data includes the import address table, string constants, static global data, and so on.

Vea tambiénSee also

Convenciones de llamadaCalling Conventions