基本情報技術者 2010年 春期 午後 問12
次のアセンブラプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
浮動小数点数の加算を行う副プログラムFADDである。
(1) 浮動小数点数は、メモリ中の連続する2語に次の形式で格納する。

この形式で表される浮動小数点数はである。
S = E = M = 0でゼロを表現する(M = 0のときは、必ずS = E = 0であること)。
(2) FADDは、被加数と加数について、いずれか指数の大きい方にもう一方の指数をそろえてから仮数を加算し、結果がゼロの場合を除き正規化(仮数部の最上位ビットが1となるように指数部を調整)する。指数部調整の過程で、アンダフロー(指数部が0未満になるので正規化が不可能)、オーバフロー(指数部が255を超えるので正規化が不可能)は発生しないものとする。

(3) FADDは、被加数X、加数Y及び結果Zの格納領域の先頭番地を、それぞれGR1、GR2、GR3に設定して呼び出される。
(4) FADDから戻るとき、汎用レジスタGR1〜GR7の内容は元に戻す。

設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
aに関する解答群
ア:ADDL GR4,GR5
イ:ADDL GR5,GR4
ウ:LD GR4,GR5
エ:LD GR5,GR4
オ:SRL GR4,0,GR5
カ:SRL GR5,0,GR4
bに関する解答群
ア:JMI ADDMXY
イ:JMI XMINUS
ウ:JMI YMINUS
エ:JPL ADDMXY
オ:JPL XMINUS
カ:JPL YMINUS
cに関する解答群
ア:JOV ADDMXY
イ:JOV SCHECK
ウ:JPL ADDMXY
エ:JPL SCHECK
オ:JUMP ADDMXY
カ:JUMP SCHECK
dに関する解答群
ア:SLL GR5,0,GR4
イ:SLL GR5,1
ウ:SRA GR5,0,GR4
エ:SRA GR5,1
オ:SRL GR5,0,GR4
カ:SRL GR5,1
eに関する解答群
ア:ADDL GR4,=1
イ:ADDL GR5,=1
ウ:SLL GR4,1
エ:SLL GR5,1
オ:SUBL GR4,=1
カ:SUBL GR5,=1
模範解答
a:ウ、b:エ、c:カ、d:イ、e:ア
解説
解答の導き方
浮動小数点数は、数を符号部、指数部、仮数部に分けて表す方式です。問題の形式では、値は です。Sは符号、Eは指数、Mは仮数を表します。
GRは汎用レジスタ(General Register:計算途中の値を一時的に置く場所)です。プログラムでは、GR4にXの指数、GR5にYの指数、GR6にXの仮数、GR7にYの仮数を読み込んでいます。
a:指数が大きい方にそろえる処理
本文には、指数が大きい方にもう一方の指数をそろえるとあります。指数が小さい側の仮数を右にずらすと、値を変えずに指数をそろえられます。
まず、GR3にXの指数を保存してから、CPL(Compare Logical:符号なしの値として比較する命令)でGR4とGR5を比べます。Xの指数が小さい場合はBIGEYに進みます。この時点でGR5にはYの指数が入っています。GR4を大きい方の指数にするには、GR5の値をGR4に移す必要があります。したがって、aには LD GR4,GR5 が入ります。これは解答群のウです。
その後、GR5からGR3を引いて指数の差を求め、GR6に入っているXの仮数をその差だけ右にずらします。Xの指数が大きい場合は、GR4がそのまま大きい方の指数なので、Yの仮数であるGR7を右にずらします。
b:符号が同じなら仮数を加算する処理
Xの符号を調べ、負であればXMINUSに進みます。負でなければYの符号を調べます。
JPL(Jump if Plus:直前に調べた値が正なら分岐する命令)で、Yが正ならADDMXYに進めば、正の仮数同士を加算できます。Yが負なら分岐せず、GR6からGR7を引く処理に進みます。したがって、bには JPL ADDMXY が入り、解答群のエです。
Yがゼロの場合も分岐せずに引き算へ進みますが、仮数からゼロを引いても値は変わらないため、結果は正しく求められます。
c:符号が異なるときは、差の符号を後で調べる処理
Xが負でYが正の場合は、GR7からGR6を引いています。これは、正のYの仮数から負のXの仮数を引く処理です。
ただし、どちらの仮数が大きいかは、引き算の結果を見るまで分かりません。そこで、まずSCHECKに進みます。SCHECKでは、JOV(Jump on Overflow:演算で桁あふれなどが起きたことを示すフラグが立っていれば分岐する命令)によって、引き算で借りが発生したかを調べます。借りがあれば結果は負なので、NEGMZで符号を負にし、仮数を正の大きさに直します。
この共通の符号チェックに進むには、cには JUMP SCHECK が入ります。解答群のカです。
d:仮数の最上位ビットが1になるまで正規化する処理
問題では、結果がゼロでなければ、仮数の最上位ビットが1になるように正規化するとあります。LOOPでは、JMI(Jump if Minus:調べた値の最上位ビットが1で、負の値として扱われる場合に分岐する命令)によって、仮数の最上位ビットを確認しています。
最上位ビットが1でなければ、仮数を左に1ビットずらします。仮数を2倍にする分、指数部を1減らせば、表す数の値は変わりません。そのため、dには SLL GR5,1 が入り、解答群のイです。
e:加算で桁上がりした場合の調整
同じ符号の仮数を加算した結果、桁上がりが起きると、仮数を1ビット右にずらし、最上位ビットを1に設定します。仮数を半分にする分、指数を1増やせば、元の値を保てます。
したがって、eでは指数を1増やす ADDL GR4,=1 が必要です。解答群のアです。
誤りやすいポイント
- 指数をそろえるとき、どちらの仮数を右にずらすかを逆にしないようにします。指数が小さい側の仮数を右にずらします。
- 符号が異なるときは、仮数を足すのではなく引きます。どちらの仮数が大きいかによって結果の符号が変わるため、差を求めた後に符号を確認します。
- 正規化で仮数を左にずらすときは、指数を1減らします。桁上がりの調整で仮数を右にずらすときは、指数を1増やします。
- JOVは常に「指数が範囲外になった」という意味ではありません。このプログラムでは、SUBLの直後に使われる場合、引き算で借りが発生したかを確認しています。
FAQ
Q: なぜ指数が大きい方にそろえるのですか?
A: 大きい方にそろえると、指数が小さい側の仮数を右にずらすだけで、加算できる形になります。指数の差が右にずらすビット数になります。
A: 大きい方にそろえると、指数が小さい側の仮数を右にずらすだけで、加算できる形になります。指数の差が右にずらすビット数になります。
Q: 仮数の正規化は、なぜ必要ですか?
A: 同じ値でも、仮数と指数の組合せは複数あります。最上位ビットを1にそろえることで、結果を決まった形式で表せます。
A: 同じ値でも、仮数と指数の組合せは複数あります。最上位ビットを1にそろえることで、結果を決まった形式で表せます。
Q: 負の結果でも仮数部を正の値にするのはなぜですか?
A: 符号は符号部で表し、仮数部には数の大きさを入れるためです。負の結果は、符号部を負にしたうえで、仮数部を正の大きさに直します。
A: 符号は符号部で表し、仮数部には数の大きさを入れるためです。負の結果は、符号部を負にしたうえで、仮数部を正の大きさに直します。
関連キーワード: 浮動小数点数、指数部、仮数部、正規化、桁あふれ
設問2:
問題文を見る プログラムを減算用に変更する場合、行番号27及び32の直後に追加する命令として正しい答えを、解答群の中から選べ。
なお、プログラム中のコメントは適宜読み替えるものとする。
解答群
ア:AND GR2,=#7FFF
イ:AND GR2,=#8000
ウ:OR GR2,=#7FFF
エ:OR GR2,=#8000
オ:XOR GR2,=#7FFF
カ:XOR GR2,=#8000
模範解答
カ
解説
解答の導き方
この設問では、加算用のプログラムを減算用に変えるとき、行番号27及び32の直後に加える命令を選びます。
まず、減算は「引く数の符号を反対にして足す」ことで実現できます。つまり、 は と同じです。このプログラムでは、加数の符号を反対にすれば、減算になります。
図では、浮動小数点数の先頭の語に符号を表すがあり、「正は0、負は1」とされています。行番号27及び32の命令は、どちらもGR2にの先頭の語を読み込んでいます。その直後に、の符号だけを反対にする必要があります。
符号だけを反対にするには、符号のビットを反転させます。ビットは、0または1で表す情報の単位です。排他的論理和(XOR:Exclusive OR)は、指定したビットが1の場所を反転させる演算です。
符号のビットだけを指定する値は、16ビットで表すと、16進数ではです。したがって、GR2に=#8000とのXORを行う命令を加えれば、符号だけが反転し、ほかの部分は変わりません。
この条件に合うのは、カの「XOR GR2,=#8000」です。
誤りやすいポイント
- OR GR2,=#8000は、符号を反転するのではなく、符号のビットを必ず1にします。もともと負のも負のままになるため、減算には使えません。
- XOR GR2,=#7FFFは、符号のビットではなく、それ以外のビットを反転させます。指数などの情報まで変わってしまいます。
- AND GR2,=#8000は、符号以外のビットを0にします。符号を反転する命令ではありません。
- 行番号27と32は、分岐によってどちらか一方が実行されます。そのため、どちらの経路でもの符号を反転できるよう、両方の直後に命令を追加します。
FAQ
Q: なぜの符号を反転すると減算になるのですか?
A: 負の数を足すことは、その数を引くことと同じだからです。たとえば、はとして計算できます。
A: 負の数を足すことは、その数を引くことと同じだからです。たとえば、はとして計算できます。
Q: XOR GR2,=#8000は、すでに負のの場合にどうなりますか?
A: 符号のビットが1から0に変わり、正の符号になります。正のなら、符号のビットが0から1に変わり、負の符号になります。
A: 符号のビットが1から0に変わり、正の符号になります。正のなら、符号のビットが0から1に変わり、負の符号になります。
Q: #8000を使っても、指数などの情報が変わらないのはなぜですか?
A: #8000では符号のビットだけが1で、ほかのビットは0です。XORは、指定したビットだけを反転させるため、ほかの部分はそのままです。
A: #8000では符号のビットだけが1で、ほかのビットは0です。XORは、指定したビットだけを反転させるため、ほかの部分はそのままです。
関連キーワード: 浮動小数点数、符号ビット、ビット演算、排他的論理和、減算



