10.7 __global_reg

__global_reg 記憶域クラス指定子を使用すると、コンパイラは特定のグローバル変数のためにレジスタを予約します。

構文

__global_reg( n ) type varName
各項目には以下の意味があります。
n
1 から 8 までの整数を指定します。
タイプ
以下の型のいずれかを指定します。
  • long long を除く任意の整数型。
  • 任意の文字型。
  • 任意のポインタ型。
varName
グローバル変数の名前。

使用法

__global_reg は、グローバル変数を特定のレジスタに割り当てます。--global_reg コマンドラインオプションと同じように、レジスタにグローバル変数が割り当てられない場合にそのレジスタを使用するコードをコンパイラが生成しないようにします。指定されるレジスタ番号は、1 ~ 8 の範囲内にある必要があります。これは、r4 ~ r11 の範囲にあるレジスタに対応します。

制約条件

この記憶域クラスを使用すると、 extern static 、または typedef などの追加の記憶域クラスは使用できません。
C では、グローバルレジスタ変数を宣言時に修飾または初期化することはできません。C++ では、すべての初期化が動的な初期化として処理されます。
使用されている AAPCS のバリアントに応じて、使用できるレジスタ変数の数は異なりますが、グローバル変数レジスタとして 5 ~ 7 本のレジスタを使用できます。
実際には、以下の数を超える使用は推奨しません。
  • Thumb-2 テクノロジが搭載されたプロセッサの ARM または Thumb の 3 つのグローバルレジスタ変数
  • Thumb-2 テクノロジが搭載されていないプロセッサの Thumb の 1 つのグローバルレジスタ変数
  • グローバル浮動小数点レジスタ変数として使用可能な浮動小数点レジスタの半数
多くのグローバル変数を宣言すると、コードサイズは著しく増大します。場合によっては、プログラムをコンパイルできなくなります。

注意

グローバルレジスタ変数を使用する場合は、以下の理由で注意を払う必要があります。
  • 異なるコンパイルユニット間での直接呼び出しが適切であるかどうかがリンク時にチェックされません。プログラムで使用されているグローバルレジスタ変数は、できる限り、プログラムの各コンパイルユニットで定義して下さい。一般的に、レジスタ変数の定義はグローバルヘッダファイルに配置するのが最も適切です。グローバルレジスタの値は、レジスタが使用される前に、コードの最初の段階で設定する必要があります。
  • グローバルレジスタ変数は呼び出し先退避レジスタにマッピングされるため、その値をグローバルレジスタ変数として使用しないライブラリ関数などのコンパイルユニットでは、この値が関数への呼び出しを介して保存および復元されます。
  • グローバルレジスタ変数を使用するコンパイルユニットへのコールバックは危険です。たとえば、グローバルレジスタを使用する関数が、グローバルレジスタ変数を宣言しないコンパイルユニットから呼び出されると、その関数は推測したグローバルレジスタ変数から誤った値を読み出すことになります。
  • この記憶域クラスは、ファイルの有効範囲のみで使用できます。
  • __global_reg 記憶域クラス指定子を持つ volatile 変数は、volatile として取り扱われません。

サンプル

このサンプルでは、グローバル変数 x を宣言し、その変数のために r5 を予約します。
__global_reg(2) int x; // x のために r5 が予約される
グローバルレジスタは、同じ変数のすべての宣言で指定する必要があるため、次のサンプルではエラーが発生します。
int x;
__global_reg(1) int x; // error
C では、__global_reg 変数を定義時に修飾または初期化することはできません。次のサンプルにおいて、C++ ではエラーになりませんが、C ではエラーになります。
__global_reg(1) int x=1; // C ではエラー、C++ では OK
関連する参考文書
8.91 --global_reg=reg_name[,reg_name,...]
非機密扱いPDF file icon PDF 版ARM DUI0472LJ
Copyright © 2010-2015 ARM.All rights reserved.