x64 ソフトウェア規約x64 software conventions

このセクションには、x64、x86、64 ビット拡張機能の呼び出し規約、C++ がについて説明しますアーキテクチャ。This section describes the C++ calling convention methodology for x64, the 64-bit extension to the x86 architecture.

X64 呼び出し規則の概要Overview of x64 calling conventions

X86 および x64 の 2 つの重要な違いは、64 ビットのアドレス指定機能および一般的な用途のレジスタを 16 個の 64 ビットのフラットなセット。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. 展開されたレジスタ セットを指定するには、x64 を使用して、 _ _fastcall呼び出し規約および RISC ベースの例外処理モデル。Given the expanded register set, x64 uses the __fastcall calling convention and a RISC-based exception-handling model. __fastcall規則では、最初の 4 つの引数とスタック フレームのレジスタを使用して、追加の引数を渡します。The __fastcall convention uses registers for the first four arguments and the stack frame to pass additional arguments. X64 呼び出し規則、レジスタの使用料などの詳細については、パラメーターをスタックの値、およびスタックのアンワインドを参照してください。 を返すx64 呼び出し規則します。For details on the x64 calling convention, including register usage, stack parameters, return values, and stack unwinding, see x64 calling convention.

X64 の最適化を有効にします。Enable optimization for x64

次のコンパイラ オプションでは、x64 用のアプリケーションを最適化するのに役立ちます。The following compiler option helps you optimize your application for x64:

型とストレージTypes and storage

このセクションでは、列挙型と x64 のデータ型のストレージについて説明します。 アーキテクチャ。This section describes the enumeration and storage of data types for the x64 architecture.

スカラー型Scalar types

任意の配置とデータにアクセスすることはできますが、自然な境界またはパフォーマンスの低下を回避するために、いくつかの複数のデータを整列するがお勧めします。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. 列挙型が定数の整数であり、32 ビット整数として扱われます。Enums are constant integers and are treated as 32-bit integers. 次の表には、次のアラインメント値を使用して配置に関連している型の定義とデータの推奨される記憶域がについて説明します。The following table describes the type definition and recommended storage for data as it pertains to alignment using the following alignment values:

  • 8 ビット バイトByte - 8 bits

  • Word の 16 ビットWord - 16 bits

  • 32 ビットのダブルワードDoubleword - 32 bits

  • Quadword - 64 ビットQuadword - 64 bits

  • Octaword - 128 ビットOctaword - 128 bits

スカラー型Scalar Type C データ型C Data Type ストレージ サイズ (バイト単位)Storage Size (in bytes) 推奨される配置Recommended Alignment
INT8INT8 charchar 11 ByteByte
UINT8UINT8 unsigned charunsigned char 11 ByteByte
INT16INT16 shortshort 22 WordWord
UINT16UINT16 unsigned shortunsigned short 22 WordWord
INT32INT32 intint, long 44 ダブルワードDoubleword
UINT32UINT32 unsigned int, unsigned longunsigned int, unsigned long 44 ダブルワードDoubleword
INT64INT64 __int64__int64 88 QuadwordQuadword
UINT64UINT64 unsigned __int64unsigned __int64 88 QuadwordQuadword
FP32 (単一の有効桁数)FP32 (single precision) floatfloat 44 ダブルワードDoubleword
FP64 (有効桁数を 2 倍)FP64 (double precision) doubledouble 88 QuadwordQuadword
ポインターPOINTER * 88 QuadwordQuadword
__m64__m64 構造体の _ _m64struct __m64 88 QuadwordQuadword
__m128__m128 _ _m128 の構造体struct __m128 1616 OctawordOctaword

集約と共用体Aggregates and unions

配列、構造体、共用体などの他の種類では、一貫性のある集約と共用体ストレージとデータ取得を保証するより厳密なのアラインメント要件があります。Other types, such as arrays, structs, and unions, have stricter alignment requirements that ensure consistent aggregate and union storage and data retrieval. 配列、構造、および共用体の定義を次に示します。Here are the definitions for array, structure, and union:

  • 配列Array

    連続するデータ オブジェクトの順序付きのグループが含まれています。Contains an ordered group of adjacent data objects. 各オブジェクトが呼び出されると、要素します。Each object is called an element. 配列内のすべての要素と同じサイズとデータ型であります。All elements within an array have the same size and data type.

  • 構造体Structure

    データ オブジェクトの順序付きのグループが含まれています。Contains an ordered group of data objects. 、配列の要素とは異なり、構造内のデータ オブジェクトは別のデータの種類とサイズを持つことができます。Unlike the elements of an array, the data objects within a structure can have different data types and sizes. 構造体の各データ オブジェクトが呼び出されます、メンバーします。Each data object in a structure is called a member.

  • 和集合Union

    名前付きのメンバーのセットのいずれかを保持するオブジェクト。An object that holds any one of a set of named members. 名前付きセットのメンバーは、任意の型指定できます。The members of the named set can be of any type. 共用体に割り当てられたストレージは、その共用体、および配置に必要なすべての埋め込みの最大のメンバーに必要なストレージと同じです。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.

次の表では、厳密に推奨されるスカラー共用体と構造体のメンバーの配置を示します。The following table shows the strongly suggested alignment for the scalar members of unions and structures.

スカラー型Scalar Type C データ型C Data Type 必要な配置Required Alignment
INT8INT8 charchar ByteByte
UINT8UINT8 unsigned charunsigned char ByteByte
INT16INT16 shortshort WordWord
UINT16UINT16 unsigned shortunsigned short WordWord
INT32INT32 intint, long ダブルワードDoubleword
UINT32UINT32 unsigned int, unsigned longunsigned int, unsigned long ダブルワードDoubleword
INT64INT64 __int64__int64 QuadwordQuadword
UINT64UINT64 unsigned __int64unsigned __int64 QuadwordQuadword
FP32 (単一の有効桁数)FP32 (single precision) floatfloat ダブルワードDoubleword
FP64 (有効桁数を 2 倍)FP64 (double precision) doubledouble QuadwordQuadword
ポインターPOINTER * QuadwordQuadword
__m64__m64 構造体の _ _m64struct __m64 QuadwordQuadword
__m128__m128 _ _m128 の構造体struct __m128 OctawordOctaword

次の集計の配置ルールが適用されます。The following aggregate alignment rules apply:

  • 配列の配置では、配列の要素の 1 つの配置と同じです。The alignment of an array is the same as the alignment of one of the elements of the array.

  • 構造体または共用体の先頭の配置は、個々 のメンバーの最大の配置です。The alignment of the beginning of a structure or a union is the maximum alignment of any individual member. 構造体または共用体の各メンバーは、前のメンバーによって、暗黙の型の内部の埋め込みが必要ですが、前の表で定義されている、適切なアラインメントに配置する必要があります。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.

  • 構造体のサイズは、その配置では、最後のメンバーの後にスペースを必要がありますの整数倍である必要があります。Structure size must be an integral multiple of its alignment, which may require padding after the last member. 構造体と共用体は、配列でグループ化できる、ので、構造体または共用体の配列の各要素の最初し、最後に、以前に判断する適切な配置。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.

  • 以前のルールを管理する限り、アラインメント要件より大きくなるようにデータを配置することになります。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.

  • 個々 のコンパイラでは、サイズ上の理由から、構造体のパッキングを調整できます。An individual compiler may adjust the packing of a structure for size reasons. たとえば/Zp (構造体メンバーの配置)構造体のパッキングを調整できます。For example /Zp (Struct Member Alignment) allows for adjusting the packing of structures.

構造体の配置例Examples of Structure Alignment

次の 4 つ例では、配置済みの構造体または共用体、および対応する数値は、その構造体または共用メモリ内のレイアウトを示しています。 を宣言します。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. 図内の各列は、メモリのバイトを表し、列の数がそのバイトの移動距離を示します。Each column in a figure represents a byte of memory, and the number in the column indicates the displacement of that byte. 各図の 2 行目の名前は、宣言内の変数の名前に対応します。The name in the second row of each figure corresponds to the name of a variable in the declaration. 影付きの列には、指定された配置を実現するために必要なは埋め込みが示されます。The shaded columns indicate padding that is required to achieve the specified alignment.

例 1Example 1

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

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

AMD 変換例 1 の構造体レイアウトAMD conversion example 1 structure layout

例 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
}

AMD 変換例 2 の構造体レイアウトAMD conversion example 2 structure layout

例 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
}

AMD 変換例 2 の構造体レイアウトAMD conversion example 2 structure layout

例 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
}

AMD 変換例 4 の共用体 layouitAMD conversion example 4 union layouit

ビット フィールドBitfields

構造体のビット フィールドは 64 ビットに制限されており、型は int、unsigned int、int64、または unsigned int64 の署名します。Structure bit fields are limited to 64 bits and can be of type signed int, unsigned int, int64, or unsigned int64. 型の境界を越えるビット フィールドでは、次の型の配置をビット フィールドを配置するをスキップします。Bit fields that cross the type boundary will skip bits to align the bitfield to the next type alignment. たとえば、整数のビット フィールド可能性があります、32 ビットの境界を通過しません。For example, integer bitfields may not cross a 32-bit boundry.

X86 との競合コンパイラConflicts with the x86 compiler

4 バイトが自動的に整列していません、スタック、x86 を使用する場合よりも大きいデータ型をコンパイラにアプリケーションをコンパイルします。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. のアーキテクチャを x86 コンパイラでは、4 バイトで、たとえば、64 ビットの整数よりも大きな、4 バイトのアラインされたスタックが 8 バイトのアドレスに自動的に配置することはできません。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.

アラインされていないデータの操作では、2 つの影響を与えます。Working with unaligned data has two implications.

  • アラインされていない場所へのアクセスに配置された場所にアクセスするよりも長い時間がかかる場合があります。It may take longer to access unaligned locations than it takes to access aligned locations.

  • インタロックされた操作では、アラインされていない場所を使用できません。Unaligned locations cannot be used in interlocked operations.

複数の厳密なアラインメントが必要な場合を使用して、__declspec(align(N))変数の宣言にします。If you require more strict alignment, use __declspec(align(N)) on your variable declarations. 動的に、仕様に合わせて、スタックに揃えをコンパイラに対応します。This causes the compiler to dynamically align the stack to meet your specifications. ただし、実行時にスタックを動的に調整すると、アプリケーションの実行速度が遅くが発生する可能性があります。However, dynamically adjusting the stack at run time may cause slower execution of your application.

レジスタの使用Register usage

浮動小数点の使用可能な x64 のアーキテクチャ (呼ぶ整数レジスタと)、16 個の汎用レジスタと 16 個の XMM/YMM の提供を登録します。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. volatile レジスタは、呼び出しで使用された後に内容が破棄されることが、呼び出し元によって想定されているスクラッチ レジスタです。Volatile registers are scratch registers presumed by the caller to be destroyed across a call. 関数呼び出しで使用された後もレジスタの値を保持するには非 volatile レジスタが必要です。使用された非 volatile レジスタの保存は、呼び出し先が行う必要があります。Nonvolatile registers are required to retain their values across a function call and must be saved by the callee if used.

登録の更新頻度と保持Register volatility and preservation

関数呼び出しで各レジスタがどのように使用されるかを次の表に示します。The following table describes how each register is used across function calls:

登録Register 状態Status 用途Use
RAXRAX VolatileVolatile 戻り値レジスタReturn value register
RCXRCX VolatileVolatile 1 番目の整数引数First integer argument
RDXRDX VolatileVolatile 2 番目の整数引数Second integer argument
R8R8 VolatileVolatile 3 番目の整数引数Third integer argument
R9R9 VolatileVolatile 4 番目の整数引数Fourth integer argument
R10:R11R10:R11 VolatileVolatile 必要に応じて、呼び出し元によって保持される必要があります。syscall/sysret 命令で使用されます。Must be preserved as needed by caller; used in syscall/sysret instructions
R12:R15R12:R15 非 volatileNonvolatile 呼び出し先によって保持される必要があります。Must be preserved by callee
RDIRDI 非 volatileNonvolatile 呼び出し先によって保持される必要があります。Must be preserved by callee
RSIRSI 非 volatileNonvolatile 呼び出し先によって保持される必要があります。Must be preserved by callee
RBXRBX 非 volatileNonvolatile 呼び出し先によって保持される必要があります。Must be preserved by callee
RBPRBP 非 volatileNonvolatile フレーム ポインターとして使用できます。呼び出し先によって保持される必要があります。May be used as a frame pointer; must be preserved by callee
RSPRSP 非 volatileNonvolatile スタック ポインターStack pointer
XMM0, YMM0XMM0, YMM0 VolatileVolatile 1 番目の FP 引数。__vectorcall が使用された場合の 1 番目のベクター型引数。First FP argument; first vector-type argument when __vectorcall is used
XMM1, YMM1XMM1, YMM1 VolatileVolatile 2 番目の FP 引数。__vectorcall が使用された場合の 2 番目のベクター型引数。Second FP argument; second vector-type argument when __vectorcall is used
XMM2, YMM2XMM2, YMM2 VolatileVolatile 3 番目の FP 引数。__vectorcall が使用された場合の 3 番目のベクター型引数。Third FP argument; third vector-type argument when __vectorcall is used
XMM3, YMM3XMM3, YMM3 VolatileVolatile 4 番目の FP 引数。__vectorcall が使用された場合の 4 番目のベクター型引数。Fourth FP argument; fourth vector-type argument when __vectorcall is used
XMM4, YMM4XMM4, YMM4 VolatileVolatile 必要に応じて、呼び出し元によって保持される必要があります。__vectorcall が使用された場合の 5 番目のベクター型引数。Must be preserved as needed by caller; fifth vector-type argument when __vectorcall is used
XMM5, YMM5XMM5, YMM5 VolatileVolatile 必要に応じて、呼び出し元によって保持される必要があります。__vectorcall が使用された場合の 6 番目のベクター型引数。Must be preserved as needed by caller; sixth vector-type argument when __vectorcall is used
XMM6:XMM15, YMM6:YMM15XMM6:XMM15, YMM6:YMM15 非 volatile (XMM)、volatile (YMM の上半分)Nonvolatile (XMM), Volatile (upper half of YMM) 呼び出し先によって保持される必要があります。Must be preserved by callee. 必要に応じて、呼び出し元によって YMM レジスタが保持される必要があります。YMM registers must be preserved as needed by caller.

関数の終了と C ランタイム ライブラリの呼び出しおよび Windows システムの呼び出しを関数のエントリは、CPU の方向フラグをクリアするフラグの登録が必要です。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.

スタックの使用Stack usage

スタック割り当て、配置、関数の型および x64 のスタック フレームの詳細については、「 x64 スタックの使用状況します。For details on stack allocation, alignment, function types and stack frames on x64, see x64 stack usage.

プロローグとエピローグProlog and epilog

スタック領域の割り当て、その他の関数を呼び出し、不揮発性レジスタを保存または例外処理を使用するすべての関数のプロローグに関連付けられた各関数のテーブルのエントリとエピローグのアンワインド データのアドレスの制限が説明されている必要があります。関数を各終了します。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. 必要なプロローグの詳細と x64 のエピローグ コードは、次を参照してください。 x64 プロローグとエピローグします。For details on the required prolog and epilog code on x64, see x64 prolog and epilog.

x64 例外処理x64 exception handling

規則と構造化例外処理と C++ 例外処理、x64 での動作を実装するために使用するデータ構造については、次を参照してください。 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.

組み込みおよびインライン アセンブリIntrinsics and inline assembly

1 つ、x64 の制約のコンパイラは、インライン アセンブラーのサポートがないようにします。One of the constraints for the x64 compiler is to have no inline assembler support. つまり、関数は、サブルーチン、またはコンパイラによってサポートされる組み込み関数として記述する必要がいずれかの C または C++ で記述することはできません。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. 特定の関数はパフォーマンスと小文字が区別されないものもあります。Certain functions are performance sensitive while others are not. パフォーマンスが重視される関数は、組み込み関数として実装する必要があります。Performance-sensitive functions should be implemented as intrinsic functions.

コンパイラでサポートされている組み込み関数は「コンパイラ組み込みします。The intrinsics supported by the compiler are described in Compiler Intrinsics.

イメージの形式Image format

X64 実行可能イメージ形式は、pe 32 + します。The x64 executable image format is PE32+. (Dll と Exe) の実行可能イメージは、静的なイメージのデータに対処する 32 ビットの変位相対アドレスを使用できるように、2 ギガバイト単位の最大サイズに制限されます。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. このデータにはインポート アドレス テーブル、文字列定数、グローバルな静的データ、およびなどが含まれます。This data includes the import address table, string constants, static global data, and so on.

関連項目See also

呼び出し規約Calling Conventions