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 
 |