A.1.2 通常時と割り込み時に使用する変数を定義する

通常時の処理と割り込みの処理の両方で使用する変数は,volatile指定してください。

volatile修飾子をつけて変数宣言すると,その変数は最適化の対象になりません。volatile指定された変数に対する操作を行うときは,必ずメモリから値を読み込み,volatile指定された変数に値を代入するときは必ずメモリへ値を書き込みます。また,volatile指定された変数のアクセス順序,アクセス幅,およびアクセス回数も変更されません。volatile指定されていない変数は,最適化によってレジスタに割り付けられ,その変数をメモリからロードするコードが削除されることがあります。また,volatile指定されていない変数に同じ値を代入する場合,冗長な処理と解釈されて最適化によりコードが削除されることもあります。

例 1.

volatile 指定しなかった場合のソースと出力コードイメージの例
“変数a” ,“変数b”をvolatile 指定しなかった場合,これらの変数がレジスタに割り付けられ,最適化される場合があります。

int a;
int b;
void func(void){
    if(a <= 0){
        b++;
    } else {
        b+=2;
    }
    b++;
}
 
 
 
 
 
_func:
        movw    ax, !LOWW(_a)
        xor     a, #0x80
        cmpw    ax, #0x8001
        movw    ax, !LOWW(_b)
        bnc     $.BB@LABEL@1_3
.BB@LABEL@1_1:          ; bb1
        incw    ax
.BB@LABEL@1_2:          ; bb9
        incw    ax
        movw    !LOWW(_b), ax
        ret
.BB@LABEL@1_3:          ; bb3
        incw    ax
        br      $.BB@LABEL@1_1

例 2.

volatile指定した場合のソースと出力コードの例
“変数a”,および“変数b”をvolatile指定した場合,これらの変数値を必ずメモリから読み込み,値を代入するときはメモリへ書き込むコードが出力されます。

volatile指定をすると,メモリの読み込み/書き込み処理が入るため,volatile指定しなかった場合よりもコード・サイズは大きくなります。

volatile int a;
volatile int b;
void func(void){
    if(a <= 0){
        b++;
    } else {
        b+=2;
    }
    b++;
}
 
 
 
 
 
 
_func:
        movw    ax, !LOWW(_a)
        xor     a, #0x80
        cmpw    ax, #0x8001
        bnc     $.BB@LABEL@1_2
.BB@LABEL@1_1:          ; bb1
        onew    ax
        br      $.BB@LABEL@1_3
.BB@LABEL@1_2:          ; bb3
        movw    ax, #0x0002
.BB@LABEL@1_3:          ; bb3
        addw    ax, !LOWW(_b)
.BB@LABEL@1_4:          ; bb9
        movw    !LOWW(_b), ax
        incw    !LOWW(_b)
        ret