キャリーフラグとオーバーフローフラグの違い、わかりますか?

キャリーフラグ(CF)もオーバーフローフラグ(OF)も、演算をした結果がレジスタに納まらないときに立つフラグですが、二つはどう違うのでしょうか。

簡単にいうと、キャリーフラグは「符号なし演算」のための桁あふれフラグであり、オーバーフローフラグは「符号付き演算」のための桁あふれフラグです。

キャリーフラグ

定義

CFは符号無し演算のときなどに意味をなすフラグです。二つのオペランドの最上位ビット(MSB)をA,Bとし、MSBよりも一つ低いビットからの桁上がりをCY_INとすると、論理式では、

CF = A・B + B・CY_IN + CY_IN・A

と表せます。

つまり、A, B, CY_INのいずれか2つ以上が1であれば、CFが立ちます。

これは、符号なしの二つの数をX, Yとすると、「二つを足し合わせたもの(X + Y =) Zが、Xよりも小さい(Z < X)ときにCFが立つ」、と言いかえることも出来ます。

例えば、8ビットのレジスタで

FFh + 01h ;255 + 1

を計算すると、8ビットでは桁が足りないため、256を意味する100hではなく、

00h

となります。そして、この計算ではA=1, B=0, CY_IN=1であり、キャリーフラグが立つことになります。

オーバーフローフラグ

定義

一方、OFは符号有り演算のときなどに意味をなすフラグです。先ほどと同様に二つのオペランドのMSBをA,Bとし、加算結果のMSBをCとすると、論理式では、

OF = A・B・_C + _A・_B・C

と表せます。_はNOTの意味です。

つまり、AがBと等しくCと違う(A = B, A != C)ときにOFが立ちます。

これは符号有りの加算で考えると、MSBが符号に対応することに注意して、

  1. 負(X < 0)と負(Y < 0)の和(Z = X + Y)が正(Z > 0)となるか、
  2. 正(X > 0)と正(Y > 0)の和が負(Z < 0)となる

ときにOFが立つ、と言うことができます。なお、正と負の加算では、必ず期待通りの値が得られるのでフラグは立ちません。

例えば、

7Fh + 01h ;127 + 1

を計算すると、符号有りの計算ではMSBは符号を表しているため、128とはならず、

80h ;-128

となります。そして、この計算ではA = 0, B = 0, C = 1であり、OFが立つことになります。

参考

このような、どういう演算をしたときにフラグが立つかという話は、アセンブリの本よりも、デジタル電子回路の本の方が詳しいです。そのため、もっと詳しいことを知りたい方は、デジタル回路の本をお勧めします。

おすすめの本

おすすめの本は次の通りです。

ハッカーのたのしみ―本物のプログラマはいかにして問題を解くか

今回の話のような論理演算を活用する話題が豊富な本。タイトルから想像される本の内容とは異なります。辞書的にも使えます。

OD>ハッカ-のたのしみ: 本物のプログラマはいかにして問題を解くか

CPUの創りかた

CPU(MPU)内部で行われる論理演算をICで組んで学ぶことができる本。表紙から想像されるようにわかりやすく書かれていて人気の本です。ICで組むのは大変そうだったので、私はCPLDで組みました

CPUの創りかた

 

VHDLによるディジタル回路入門

デジタル電子回路の基本をVHDLを使って覚える本。amazonレビューにあるようにVHDLを覚えようという人向けではないのですが、デジタル電子回路を学ぼうという人には最適だと思います。

改訂版 VHDLによるディジタル回路入門

旧版のレビューも参考になります。

VHDLによるディジタル回路入門