昔々の世界では、減算命令がないCPUもありました。そこで前にも
説明したように「2の補数」という概念を用いて減算を実行してきました。現在のCPUでは、
どんなに安いCPUにも減算命令は用意されています。
SUB DEST,SRC
動作:DEST←DEST-SRC
影響を受けるフラグ:OF,SF,ZF,AF,CF,PF
DEST:レジスタ、メモリー
SRC :レジスタ、メモリー、即値 (ただしメモリー、メモリーの組み合わせは除く)
|
SBB DEST,SRC
動作:DEST←DEST-SRC-CF
影響を受けるフラグ:OF,SF,ZF,AF,CF,PF
DEST:レジスタ、メモリー
SRC :レジスタ、メモリー、即値 (ただしメモリー、メモリーの組み合わせは除く)
|
減算命令も加算命令と同様にキャリーフラグを考慮する「SBB」と考慮しない「SUB」の
2つの命令が用意されている。
「SUB」命令では、DEST(引かれる数)がSRC(引く数)より小さく結果がマイナスになる場合
は加算と逆に、桁を借りてくる。我々が日常計算する場合、引かれる数の方が小さいと、
とりあえず大きい方から小さい方を引いて、頭にマイナスをつける。例えば、「5-10」は
引かれる数の方が小さいので、とりあえず大きい数(10)から小さい数(5)を引いて、
マイナスをつけ「-5」とする。
アセンブラの場合はもう1桁増やし、その桁が1であると仮定して計算する。例えば、
「5Bh-85h」を計算すると、図のようになる。引かれる数(5Bh)の方が小さいので、
さらに1桁上に「1」があると仮定して、15Bh-85h=D6hとなる。この場合、桁借りをしたので
キャリーフラグが1になる。(OF=0,SF=1,ZF=0,他のフラグは省略)
「SBB」命令では、キャリーフラグが1ならば、さらに1を引く。すなわち前の
引き算の結果、桁借りを起こしていたら、その分も引くことになり、「ADD」命令
の後に、「ADC」命令を実行したのと同様に、「SUB」命令後必要ならば「SBB」命令
を行う。
「SUB」「SBB」どちらも、フラグは同様に変化し、キャリーフラグは今説明した
通りである。ZFは減算の結果が0であればZF=1、それ以外ならZF=0になる。
符号付き整数の減算を考えた場合、80h(-127)-1=7Fh(+127)となり、引き算を
したはずなのに、結果が大きくなってしまった場合に、オーバーフローを起こしたと言い、
オーバーフローフラグOF=1となる。オーバーフローを起こさなかった場合には0になる。
符号なし整数の場合はOFは無視して構わない。
符号なし、符号付き整数のどちらも計算結果の上位1bitが1ならばSF=1、上位1bitが
0ならばSF=0となる。そのほかのフラグについては省略する。