基本情報技術者 2011年 秋期 午後 問12
次のアセンブラプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラム1の説明〕
除算を行う副プログラムDIVである。
(1) DIVは表1に示すレジスタを介して、被除数と除数を受け取り、商と剰余を返す。数値は全て32ビットの符号なし整数とし、除数は0でないものとする。


(2) 副プログラムDIVから戻るとき、汎用レジスタGR6, GR7の内容は元に戻す。

設問1:
問題文を見る プログラム1中のに入れる正しい答えを、解答群の中から選べ。
aに関する解答群
ア:ADDL GR1,0,GR3
イ:ADDL GR1,=1
ウ:ADDL GR2,1,GR3
エ:ADDL GR2,=1
オ:ADDL GR4,0,GR3
カ:ADDL GR5,1,GR3
bに関する解答群
ア:JMI ADJ2
イ:JMI CONT
ウ:JOV ADJ2
エ:JOV CONT
オ:JPL ADJ2
カ:JPL CONT
模範解答
a:イ、b:ウ
解説
解答の導き方
この問題では、除算の処理のうち、商を増やす部分と、剰余を減らす部分を完成させます。まず、32ビットの値を上位16ビットと下位16ビットに分けて考えます。
1. 商の下位語があふれたら、上位語を増やします
表1では、商をGR1(上位語)とGR2(下位語)で受け取ります。プログラムは、商をGR1、GR2ともに「=#FFFF」にした後、ループのたびに「ADDL GR2,=1」で下位語を1増やします。
GR2が「=#FFFF」のときに1を加えると、下位語は0に戻り、桁上がりが発生します。この桁上がりを上位語に反映するには、GR1を1増やす必要があります。その処理を行う命令が「ADDL GR1,=1」です。
したがって、aには「ADDL GR1,=1」が入ります。選択肢は イ です。
商の初期値が上位語・下位語ともに「=#FFFF」なのは、最初のループで商を増やすと0になるようにするためです。その後、除数を引けた回数に応じて商が増えていきます。
2. 下位語の減算で桁借りが発生したら、上位語を1減らします
表1によると、除数はGR3が示すアドレスから、上位語、下位語の順に格納されています。そのため、プログラムでは、まず「SUBL GR6,0,GR3」で上位語を引き、その後「SUBL GR7,1,GR3」で下位語を引いています。
上位語の減算で桁借りが発生した場合は、除数が現在の剰余より大きいと判断できるため、「JOV FIN」で処理を終了します。
上位語の減算ができた後、下位語の減算で桁借りが発生した場合は、32ビットの値全体では上位語を1減らす必要があります。上位語を1減らす処理は「ADJ2」にあります。そのため、下位語の減算後にオーバーフローが発生した場合、「ADJ2」へ分岐させます。
したがって、bには「JOV ADJ2」が入ります。選択肢は ウ です。
3. 減算できなかったときに、剰余を元に戻せる理由
ループの冒頭では、減算前の剰余を「LD GR4,GR6」「LD GR5,GR7」でGR4、GR5に保存しています。除数を引けなかった場合、GR6、GR7の値は減算の途中で変わっている可能性があります。そのため、保存しておいたGR4、GR5を出力すれば、正しい剰余を返せます。
誤りやすいポイント
-
下位語の桁上がりと、上位語の更新を混同しないようにします。
商の下位語はGR2、上位語はGR1です。GR2から桁上がりが出たときに増やすのは、GR1です。 -
下位語の減算で桁借りが出たときは、上位語を減らします。
加算の桁上がりでは上位語を増やし、減算の桁借りでは上位語を減らします。 -
JOVを、単に「結果が負なら分岐する」と考えないようにします。
この処理では、ADDLやSUBLによってオーバーフローが発生したかどうかを見ています。下位語の減算で桁借りが起きた場合に必要なのは、ADJ2への分岐です。
FAQ
Q: なぜ商を「=#FFFF」から始めるのですか?
A: 商を増やしてから除数を引く処理だからです。最初の試行で商が0になり、除数を引けた回数と商が一致するようにしています。
A: 商を増やしてから除数を引く処理だからです。最初の試行で商が0になり、除数を引けた回数と商が一致するようにしています。
Q: なぜ下位語を引く前に、上位語を引くのですか?
A: 先に上位語を比べると、除数が剰余より大きいかを判断しやすいためです。下位語の減算で桁借りが起きた場合は、その分だけ上位語を調整します。
A: 先に上位語を比べると、除数が剰余より大きいかを判断しやすいためです。下位語の減算で桁借りが起きた場合は、その分だけ上位語を調整します。
Q: GR4、GR5には何を保存していますか?
A: 減算前の剰余です。除数を引けなかったとき、減算途中の値ではなく、保存しておいた値を剰余として返すために使います。
A: 減算前の剰余です。除数を引けなかったとき、減算途中の値ではなく、保存しておいた値を剰余として返すために使います。
関連キーワード: 32ビット演算、上位語・下位語、桁上がり、桁借り、オーバーフローフラグ
設問2:
問題文を見る 10進表記で0~99999の値の整数を32ビット符号なし整数として与えたとき、DIVを用いて10進数文字列に変換する副プログラムBTODを異なるアルゴリズムで2種類作成した。プログラム2は10進表記の上位桁から求めるものであり、プログラム3は10進表記の下位桁から求めるものである。プログラム2, プログラム3中のに入れる正しい答えを、解答群の中から選べ。
(1) BTODは32ビット符号なし整数の上位語をGR1に、下位語をGR2に、変換結果を格納する領域の先頭アドレスをGR3に設定して呼び出される。
(2) 変換後の10進数文字列は5語の領域に格納される。ただし、5桁に満たない場合は上位桁に“0”が補われる。対象数値が16進表記で0000054Dの場合の実行結果を、次に示す。
GR1 0000 (GR3)→ '0' '1' '3' '5' '7'
GR2 054D
(3) 副プログラムBTODから戻るとき、汎用レジスタGR1~GR7の内容は元に戻す。

c, eに関する解答群
ア:GR1
イ:GR2
ウ:GR3
エ:GR4
オ:GR5
dに関する解答群
ア:LAD GR3,1,GR3
イ:LAD GR3,2,GR3
ウ:LAD GR7,1,GR7
エ:LAD GR7,2,GR7
オ:LD GR3,1,GR3
カ:LD GR3,2,GR3
キ:LD GR7,1,GR7
ク:LD GR7,2,GR7
fに関する解答群
ア:1
イ:10
ウ:100
エ:1000
オ:10000
模範解答
c:イ、d:イ、e:オ、f:イ
解説
解答の導き方
まず、DIVが受け取る値と返す値を確認します。レジスタ(CPU内で値を一時的に置く場所)は、問題文の表1では、被除数をGR1とGR2、除数の場所をGR3で受け取ります。除数は上位16ビットと下位16ビットの2語で置かれています。DIVは商をGR1とGR2に、剰余をGR4とGR5に返します。
プログラム2とプログラム3は、同じDIVを使いますが、10進数の桁を取り出す順序が異なります。
プログラム2:上位桁から求める
プログラム2のUDATには、除数として1000、10、が並んでいます。それぞれ2語で表すため、たとえばは上位語が、下位語がです。
入力例のは、10進数ではです。から順に割ると、商が上位桁から求まります。
どの段階でも商は~です。そのため、商の上位語GR1はで、1桁の値は下位語GR2に入ります。本文の「10進数字1文字格納」の処理では、商を文字に変えて保存するので、cにはGR2を指定します。
各除数は2語で並んでいます。次の除数の上位語に移るには、GR3を2語分進める必要があります。アドレスを計算するLADを使い、GR3にを加える LAD GR3,2,GR3 が入るので、dはイです。LDは指定先の値を読み込む命令なので、ここで使うとアドレスを進められません。
割り算の後、次の被除数には商ではなく剰余を使います。本文にある「LD GR1,GR4」「LD GR2,GR5」は、その剰余を次の計算の被除数に設定する処理です。表の商を上位桁から並べると、結果は「01357」になります。
プログラム3:下位桁から求める
プログラム3は、出力先の末尾から先頭へ向かって文字を格納します。GR6が末尾、GR7が先頭を指すように設定されています。
1桁ずつ下位から取り出すには、毎回で割ります。商は残りの上位桁、剰余は取り出した1桁です。たとえばをで割ると、商は、剰余はです。剰余が一の位になります。
剰余は~なので、上位語GR4は、1桁の値は下位語GR5に入ります。したがって、剰余を文字にするORの対象はGR5です。eはオになります。
DATの除数は2語で表されます。上位語がで、下位語にを置くため、fはイです。プログラム3では毎回同じで割り、出力先を1語ずつ先頭側へ戻します。こうして下位桁から格納しても、最後には「01357」と上位桁から読める並びになります。
なお、ORは、2進数の各桁を組み合わせる演算です。このプログラムでは数値の1桁を文字「0」~「9」の形にしてから、出力先に保存しています。
誤りやすいポイント
- 商と剰余の格納先を取り違えないようにします。DIVでは商がGR1とGR2、剰余がGR4とGR5に返ります。
- プログラム2では、次の桁を求める被除数に剰余を使います。商を使うのではありません。
- プログラム2の除数は1つにつき2語です。GR3を1語だけ進めると、次の除数の上位語ではなく下位語を指してしまいます。
- プログラム3では、剰余が次の桁です。商は次の回の被除数として残し、出力先を末尾から先頭へ動かします。
- プログラム2は桁を上位から求め、プログラム3は下位から求めます。どちらの方法でも、5桁に満たない部分には「0」が入ります。
FAQ
Q: プログラム2で、割り算の商を次の計算に使わないのはなぜですか?
A: 次の桁を求めるには、すでに取り出した上位桁を除いた残りを使う必要があるためです。その残りが剰余です。
A: 次の桁を求めるには、すでに取り出した上位桁を除いた残りを使う必要があるためです。その残りが剰余です。
Q: プログラム3では、なぜ毎回同じで割るのですか?
A: で割ると、剰余として一番下の桁を取り出せるからです。商には、それより上の桁が残ります。
A: で割ると、剰余として一番下の桁を取り出せるからです。商には、それより上の桁が残ります。
Q: GR3を進める命令にLADを使うのはなぜですか?
A: GR3が示すアドレスを次の位置へ動かすためです。LDのようにメモリの値を読み込む処理ではありません。
A: GR3が示すアドレスを次の位置へ動かすためです。LDのようにメモリの値を読み込む処理ではありません。
関連キーワード: 32ビット整数、除算、商と剰余、レジスタ、文字コード、アセンブリ言語



