なぜレジスタ内のフラグは1を書くと0になるように作られているのか
以前「このレジスタのこのフラグのビットをクリアするにはこのビットに1を書き込むとあるが、ビットを0にするには該当するビットに0を書くのではないか?」ということを聞かれたことがある。
マイコンを使った電子工作などでレジスタを直接操作するプログラムを書いたことがあればそんなことは当たり前だと感じるが、なぜそのような構成なのか説明しろと言われて説明できるだろうか?と思ったので一例として説明を考えた。
- 仮定
ある8ビットのレジスタRがあり、Rの各ビットはHWに特定のイベントが起きた際に0から1となるとする。(SWはこれを定期的に読み出し、特定のビットが0から1になったことを調べることで各ビットに対応したイベントが発生したことを知ることができる)。
各ビットに対応するイベントが発生した際に対応する特定の処理を行うため、SWは以下のフローチャートのような処理を一定時間ごとに繰り返し行う。
今、Rのビット0がHWのイベントにより0から1になったとする。
- Rが自由にR/W可能とすると
(2)においてビット0をクリアするにはRにビット0を0にしたデータを書き込む必要がある。
ビット0以外のビットには、1を書き込んで1にしてしまうと、HWのイベントが発生していないのにイベントが起きたことになってしまうため1を書き込むことはできない。
0を書くとするとRには0x00を書くことになるが、もし(1)の後、(2)にてRに0x00を書き込む前に他のイベントが発生してビット0以外が1となった場合、0x00を書き込むことでビット0以外も0になるので、そのイベントが発生したことを知ることはできなくなる。
- Rの各ビットに1を書き込むとそのビットが0にクリアされる(0を書き込んでもそのビットには影響なし)とすると
(2)においてビット0をクリアするにはビット0を1としたデータをRに書き込む必要がある。
ビット0以外には0を書き込めばよい。1を書き込むと前述のR/W可能な場合の時と同じようにイベント発生のタイミング次第で問題が起きる。
このように「1を書き込むと0になる」という構成は、レジスタのビットでSWの動作と独立して動くHWからのイベントによるフラグを表す場合に役立つ。割り込みフラグの場合もほぼ同じ。0を書き込むと0にクリア、1を書き込んでも何もしない、としても同じことだが、そのようにした例は私は見たことがない。
「1を書き込むと0になる」という表現はよく見かけるが「0を書き込んでもそのビットには影響なし」ということがレジスタ仕様に書かれていないことがあるので、重箱の隅をつっつくのが好きな人はそういうところに突っ込みを入れるかもしれない。