適用範囲: ARM Developer Suite(ADS), RealView Compilation Tools(RVCT), ARM Compiler Toolchain
8バイトスタックアライメントとは?
8バイトスタックアライメントは、ARM Architecture Procedure Call Standard [AAPCS]の要求事項です。これは、関数は全ての外部インターフェイスに対して、8バイトのアライメントされたスタックアドレス(例: 0x00, 0x08, 0x10, 0x18, 0x20)を管理する必要があることを定義しています。実際には次のような場合にこの要求事項が満たされます:
- それぞれの外部インターフェイスにおいて、現在のスタックポインタは8バイトの倍数をとります。
- 使われているOSが8バイトスタックアライメントをその外部インターフェイスで扱います。例:タスクスイッチ
8バイトスタックアライメントはLDRDおよびSTRD命令をサポートしているARMv5TEのようなプロセッサにおいて特別な利点をもたらします。スタックが8バイト以外のアライメントを持つ場合、LDRDおよびSTRD命令はターゲットと使われている設定によってはアライメントフォルトを発生させる可能性があります。
RVCTおよびARM Compiler Toolchainでの8バイトスタックアライメントについて
RealView Compilation Tools (RVCT) v2.0およびそれ以上では、全ての生成されたコードおよびCライブラリコードでは外部インターフェイスにおいて8バイトスタックアライメントを扱います。生成されたコードは、例えばリーフ関数の場合、内部的に8バイトアラインを保持しない可能性があります。しかしながら、全ての生成されたコードは8バイトアラインのスタックを保持し、関数の入り口においてすでに正しくアラインされたものを供給するでしょう。コンパイラはミスアラインされたスタックを修正するようなコードを生成しないでしょう。
8バイトスタックアライメントはRVDSでの新しい機能ではないことに注意してください。ADSは8バイトスタックアライメントを扱っていますが、"double"および"long long"のアライメントについてのみADSとRVDSで違いがあります。ADSでは"double"および"long long"データタイプは-Oldrdオプションまたは__alignの使用なしには、4バイトアライン("EBA4")となります。RVCTv2.0以降では、"double"および"long long"}データタイプは&color(red){--apcs /adsabiが使用されていなければ、8バイトアライン("EBA8")となります。
コンパイラは古いADS ABIとの互換性を保つコードをコンパイルするために--apcs /adsabiオプションをサポートしています。しかしながら、これは非推奨であり、RVDSv3.1以降では廃止されました。
RVCTおよびARM Compiler Toolchainは8バイトスタックアライメントをREQUIRE8およびPRESERVE8の2つのビルド属性を用いてチェックします。これらはいずれも真または偽でありえます。これらはツールによってオブジェクトファイルまたは実行形式に組み込まれます。REQUIRE8はスタックポインタが8バイトアラインであるようにコードに要求することを示すために用いられます。PRESERVE8は8バイトスタックアライメントをコードが保持することを示すために用いられます。
アセンブラはREQUIRE8およびPRESERVE8ディレクティブをREQUIRE8およびPRESERVE8ビルド属性が真であるか偽であるかを示す為に用います。PRESERVE8を省略すると、アセンブラはSPを修正する命令を調べて、PRES8ビルド属性をセットするかどうかを判断します。ARMはPRESERVE8を明示的に定義することを推奨します。もしアセンブラが8バイトアラインであることをスタックに要求するなら(例:SPを使用するLDRD)、REQUIRE8ディレクティブを用いなければなりません。
RVCTv2.1以降ではアセンブラ(armasm)はスタックを8バイトアラインではないままにするようなスタックアクセスを検出するとワーニングを発生させます。これはアセンブラコマンドラインにおいて、--diag_warning 1546を用いることで有効になります。
REQUIRE8およびPRESERVE8ビルド属性はコンパイラおよびアセンブラによってセットされ、リンカが8バイトアラインを保持しない8バイトアライメントな関数呼び出しを必要とする関数を呼び出さないようにします。 この状況が発生するとリンカは以下のようなエラーを発生させます:
Error: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function
より詳細については、リンカエラー: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function foobarが発生しました を参照ください。