メモリマップドI/Oポートへのアクセスとvolatile修飾子による最適化抑止

メモリマップドI/O(Memory-Mapped I/O) では、I/Oポートが通常の主記憶と同じメモリアドレス空間に割り当てられており、C言語では特定のアドレスを指すポインタを経由して通常のメモリ読み書き構文でアクセスします。しかし、I/Oポートのレジスタ値はハードウェアによって非同期に変化したり、同じアドレスへの連続した書込み自体がハードウェア制御コマンドとして意味を持ったりするため、コンパイラが「不要な重複アクセスの削除」や「レジスタ保持によるメモリアクセス省略」などの最適化を行ってしまうと正常に動作しなくなります。これを防ぐために、対象のアドレスへのポインタには `volatile`型修飾子 (常に実メモリへのアクセスを強制する修飾子)を付与して宣言する必要があります。したがって、正解は イ です。 ア: 専用のIN/OUT命令を用いるのは「I/OマップドI/O(ポートマップドI/O)」の場合であり、メモリマップドI/Oでは通常のメモリアクセス命令(LOAD/STORE)でアクセスします。 ウ: 他の関数からの可視性を限定するために static (静的)宣言することはカプセル化の手法ですが、I/Oポートアクセス特有の注意点ではありません。 エ: メモリマップドI/Oの特定番地にアクセスするには、メモリアドレス値を直接保持・型キャストしたポインタを使用するのが標準的です。

メモリマップドI/OのI/OポートにアクセスするプログラムをC言語で記述するときの注意点として,適切なものはどれか。

出典令和2年度 10月特別 エンベデッドシステムスペシャリスト試験 午前Ⅱ 問1
ア
アセンブラのIN/OUT命令を用いたアクセス用関数を呼び出して,アクセスする。
イ
コンパイラによる最適化を抑止するために,volatile型修飾子を付けて宣言した変数へのポインタとしてアドレスを指定して,アクセスする。
ウ
他の関数からアクセスされるのを防ぐために,静的広域変数として宣言してアクセスする。
エ
ポインタではアクセスできないので,配列として実体を宣言してアクセスする。