令和2年度 10月 午前Ⅱ 問1
オペレーティングシステム
メモリマップドI/Oの問題
メモリマップドI/OのI/OポートにアクセスするプログラムをC言語で記述するときの注意点として,適切なものはどれか。
- アアセンブラのIN/OUT命令を用いたアクセス用関数を呼び出して,アクセスする。
- イコンパイラによる最適化を抑止するために,volatile型修飾子を付けて宣言した変数へのポインタとしてアドレスを指定して,アクセスする。
- ウ他の関数からアクセスされるのを防ぐために,静的広域変数として宣言してアクセスする。
- エポインタではアクセスできないので,配列として実体を宣言してアクセスする。
答えと解説を見る
✓ これが正解イコンパイラによる最適化を抑止するために,volatile型修飾子を付けて宣言した変数へのポインタとしてアドレスを指定して,アクセスする。
解説
volatile修飾子を付けた変数へのポインタでアドレスを指定します。
メモリマップドI/Oでは、I/Oポートが主記憶と同じアドレス空間に割り当てられているので、C言語ではポインタでそのアドレスを指してアクセスします。注意すべきはコンパイラの最適化です。I/Oポートの値はプログラムとは無関係に外部の状態で変わりますが、コンパイラはそれを知らないため、同じアドレスを続けて読む処理を1回にまとめたり、書込みを省いたりすることがあります。volatile型修飾子を付けると、その変数へのアクセスが毎回実際に行われるようになり、こうした最適化を抑止できます。外から値が変わるものにはvolatile、と結び付けて覚えると見分けられます。
ほかの選択肢はなぜ違うのか
- アアセンブラのIN/OUT命令を用いたアク…:IN/OUT命令のようなI/O専用の命令は、I/Oポートを主記憶とは別のアドレス空間に置く方式で使うものです。メモリマップドI/Oでは、通常のメモリと同じ読み書きの命令でアクセスできます。
- ウ他の関数からアクセスされるのを防ぐために…:静的広域変数として宣言すると、その領域はコンパイラやリンカが主記憶上のどこかに割り当てるので、I/Oポートの決まったアドレスとは結び付きません。ほかの関数から隠すことも、ここでの注意点とは別の話です。
- エポインタではアクセスできないので,配列と…:ポインタを使えば、I/Oポートのアドレスを直接指して読み書きできます。配列として実体を宣言しても、その領域がI/Oポートのアドレスに置かれるとは限らず、目的のポートにはアクセスできません。
出典:令和2年度 10月 エンベデッドシステムスペシャリスト試験 午前Ⅱ 問1
この解説に誤りを見つけたら教えてください。直して、直した記録を残します。誤りを報告する(メールが開きます)