• ベストアンサー

8086で加算減算とキャリーフラグ

ADCとSBBはキャリーフラグによって1を加算減算するらしいのですが、そのキャリーフラグを参照するタイミングはADCやSBB自身の加算減算を行う前ですか? それともADCやSBB自身の加算減算によって立てられたキャリーフラグを参照して1を加算減算するのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • bnosuke-x
  • ベストアンサー率39% (43/110)
回答No.4

ADCとSBBはキャリーフラグも一緒に加減算を行う命令です。 ですので、 >ADCとSBBはキャリーフラグによって1を加算減算するらしいのですが、 と言う表現はあまりうまくないです。 筆算形式で書くと、   AX   BX + CF ---- という感じです。 ですから、 >そのキャリーフラグを参照するタイミングはADCやSBB自身の加算減算を行う前ですか? と言う質問には「いちおうYES」と答えておきます。 キャリーフラグの内容共々同時に演算しているからです。 そういう意味では同時です。 ですが、細かいことを言うと、実際のCPUの中ではおそらく右の桁から1ビットずつ全加算機を使って演算してゆくので、 そういう意味ではキャリーの中身を先に参照していると言えます。 そして、 >それともADCやSBB自身の加算減算によって立てられたキャリーフラグを参照して1を加算減算するのでしょうか? これはナンセンスです。 たとえば、ここに3桁の10進数しか扱えない電卓があるとして、 543+579を計算したときに桁上がりがあったからと言って最後に1を足しますか?   445 + 678 ------  1123 (← 千の位へ桁上がりが起きた=キャリー発生) で、最後に1を足すことに意義があるのかどうか?です。 キャリーフラグの第一の用途は、「桁上がり/桁下がりの事実を次の演算へ伝えることによりレジスタ幅より大きい桁の演算を容易に実現すること」です。 さっきの3桁電卓で12345+6789を計算するときは、   345 + 789 ------  1134 (← 千の位へ桁上がりが起きた=キャリー発生) この3桁の答えとしては下3桁のみをとり「134」   012   006 +   1 (←先の演算のキャリー) ------   019 (← 千の位へ桁上がりはない=キャリーなし) この3桁の答えとしては下3桁のみをとり「019」 二つをつなぎ合わせて答えは 「019134」です。 この原理で何桁の計算でもできます。 そして8086CPUの中でも16桁の2進数をつかって同じ仕組みで演算をしているのです。 まとまってない説明ですが、こんな感じでいかがでしょう。

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

あ, そうだ, 「『演算した直後のフラグの値』を使う意味がわからん」と自分で書きましたが, 「全く意味がない」わけではないですね. 「1 の補数」を使う場合には, 「最終的に最上位からキャリーが出たら最下位に 1 を加える」必要がありますから. もっとも, 8086 では「1 の補数」を使わないでしょうから, 普通の場合は「意味がない」んですが. ちなみに, いくら 8086 の時代であっても「最下位桁から 1ビットずつ全加算器を使って演算する」ことはないと思います>#4. さすがにリップルキャリーじゃなくってキャリールックアヘッドアダーじゃないかなぁ? 回路の構成は見たことがないのでわかりませんが.

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

>ADCとSBBはキャリーフラグによって1を加算減算するらしいのですが、そのキャリーフラグを参照するタイミングはADCやSBB自身の加算減算を行う前ですか? >それともADCやSBB自身の加算減算によって立てられたキャリーフラグを参照して1を加算減算するのでしょうか? どちらも違います。キャリーフラグはADCやSBB自身の加算減算時に参照されます。 adc ax,bxは、ax=ax+bx+CFの演算を行います。演算の結果で各フラグが設定され、桁上がりがあればキャリーフラグに1が設定されます。 adcの前に設定されたキャリーフラグの状態が加算に使われて、adcに結果に合わせて新たなキャリーフラグの状態が決まることになります。 例1 mov ax,0000h mov bx.0000h stc adc ax,bx でadc後はaxは0001hになりキャリーフラグは0になります。 なんのためにこの命令が必要かという視点で考えて見ましょう。 キャリーフラグは桁上がりを示すフラグです。既に調べてると思いますが、符号なし16bit同士の演算で桁上がりが起こった場合に1になるのがキャリーフラグです。 つまり、16bitの演算結果が16bitに収まらなかったときにフラグが1になる訳で、このフラグを参照することで16bit以上の演算が可能になります。 次のように使います。 mov ax,AL mov bx.BL add ax,bx mov CL,ax mov ax,AH mov bx.BH adc ax,bx mov CH,ax AL dw FFFFh AH dw 0000h BL dw 0001h BH dw 0001h CL dw 0000h CH dw 0000h でメモリ内容CH,CLはどうなるでしょう?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

当然, 「加減算をする直前の値」です. というか, 「演算した直後のフラグの値」を使う意味がわからん.

  • precog
  • ベストアンサー率22% (966/4314)
回答No.1

直前の状態を参照します。 コンピューターなどのデジタル回路は、クロックに同期して動くようになっています。 クロックを与えた瞬間に、以前の状態を元にして、新しい状態に遷移しますが、クロックを与えた後の結果がさらにそのクロック内で波及する事はありません。 もうちょっと正確に言うと、クロックを与えるのは結果を格納するレジスターです。演算機は常に入ってきた入力に応じて演算結果を遅延を伴いながら出し、レジスターの入力に供給しています。キャリーやレジスターの値が確定し、演算機の出力が安定したところにクロックがやってきて結果を取り込みます。よって参照されるのは古いキャリーの値です。キャリーフラグにも同時にクロックが与えられますので、同時にキャリーの値も更新されます。 2進演算なので細かく見ると16bitの加算器は内部でもキャリーがありますが、それはクロックの影響を受けずに、常に下位ビットから上位ビットに流れます。キャリーフラグだけがクロックに同期して記憶します。

関連するQ&A