令和元年秋期試験午後問題 問12
問12 ソフトウェア開発(アセンブラ)
次のアセンブラプログラムの説明及びプログラムを読んで,設問1~3に答えよ。
〔プログラム1の説明〕
符号が同一である二つの16ビットのパック10進数を加算する副プログラム ADDP1 である。本問では,パック10進数は,3桁の10進数の各桁をそれぞれ4ビットで表現し,最下位の4ビットに符号として,正又は0の場合は1100を,負の場合は1101を付与する数値表現とする。10進数246を,パック10進数で表現した例を,図1に示す。 符号が同一である二つのパック10進数の加算例を,図2に示す。
〔プログラム1の説明〕
符号が同一である二つの16ビットのパック10進数を加算する副プログラム ADDP1 である。本問では,パック10進数は,3桁の10進数の各桁をそれぞれ4ビットで表現し,最下位の4ビットに符号として,正又は0の場合は1100を,負の場合は1101を付与する数値表現とする。10進数246を,パック10進数で表現した例を,図1に示す。 符号が同一である二つのパック10進数の加算例を,図2に示す。
- 副プログラム ADDP1 は,加算の対象となる符号が同一である二つの16ビットのパック10進数が,GR1,GR2に設定されて,呼び出される。
- 副プログラム ADDP1 は,加算結果を GR0 に設定して呼出し元に戻る。このとき,汎用レジスタ GR1~GR7 の内容は元に戻す。ここで,加算において,10進数の百の位からの桁上がりは発生しないものとする。
広告
設問1
プログラム1中の に入れる正しい答えを,解答群の中から選べ。
a に関する解答群
- AND GR1,=#000F
- AND GR1,=#F000
- AND GR1,=#FFFF
- OR GR1,=#000F
- OR GR1,=#F000
- OR GR1,=#FFFF
b に関する解答群
- JMI MERGE
- JNZ MERGE
- JPL MERGE
- JOV MERGE
- JZE MERGE
c に関する解答群
- SLA GR1,0,GR3
- SLL GR1,0,GR3
- SLL GR1,=4
- SRA GR1,0,GR3
- SRL GR1,0,GR3
- SRL GR1,=4
解答選択欄
- a:
- b:
- c:
- a=ア
- b=ア
- c=イ
解説
ADDP1は、符号が同一である二つの16ビットのパック10進数の加算を行うプログラムです。符号が同一ということは「7 + 5」と「(-7) + (-5)」のようにどちらも計算結果の絶対値は同じなので、単純に符号部以外の部分の加算を行います。ただし、上位12ビットのうち4ビットを1桁として計算する際に、桁上がりを考慮しなくてはなりません。〔aについて〕
ここでは、加算を行う反復処理の前処理を選択します。[a]直後に行うST命令のコメント部では「符号部を退避」とし、GR1 の内容をアドレス RESULT に退避させていますが、[a]直前では GR1 に演算対象のパック10進数が格納されたままです。よって[a]では、GR1 の内容を符号部のビット列、すなわち下位4ビットに置き換える処理が必要です。
あるビット列から特定位置のビットを取り出したいときには、取り出したい位置を1としたビットマスクとのAND演算を用います。16ビットのうち下位4ビットを取り出したいので「0000 0000 0000 1111」をビットマスクとし GR1 とのAND演算を行います。ビットマスクを16進数で表すと 000F ですので「ア」の命令が適切です。
∴a=ア:AND GR1,=#000F
「イ」は上位4ビットを取り出すので誤り、「ウ」は全ビットを取り出すので誤り、「エ」「オ」「カ」はOR演算を使用していてビットを取り出しできないので誤りです。
〔bについて〕
Jから始まる分岐命令が入ります。
選択肢を見ると、どれもラベルMERGEにジャンプさせるものです。一方、ラベルMERGEにジャンプしない場合は、GR1 の値から数値"10"を減算(桁あふれ分を補正)し、GR0 に数値"1"を設定しています。この後の GR0 の動きに注目すると、ループの末尾のADDL命令で GR1 に GR0 を加算した値を設定しています。これがヒントです。
GR0 に"1"が格納されていれば、次の計算対象である4ビットの数値に"1"を加算します。逆に GR0 が初期値である"0"の場合は、ADDL命令を実行しても GR1 の値は変化しないので何もなかったのと同じです。つまり、GR0 には桁上がりの"1"を保持する役割があることがわかります。
このことから、GR1 と GR2 の加算の結果が10未満(桁上がりなし)ならラベルMERGEにジャンプ、そうでなければ次のステップを実行する手順が適切となります。加算結果が格納されている GR1 と10をCPL命令で比較すると、GR1 が10未満のときにはSF(サインフラグ)が1となり負数を示すので、JMI命令でラベルMERGEにジャンプさせることになります。
∴b=ア:JMI MERGE
〔cについて〕
直後に行うOR命令(中間結果との併合)をヒントに正しい処理を選択します。
GR1 の下位4ビットには加算結果が格納されていますが、本来この下位4ビットは「符号情報」があるべき位置なので、次に行われるOR演算(中間結果との併合)の前に、左シフトでビット列を本来の位置に戻しておかなくてはなりません。左シフトを行うのですから正解は「イ」「ウ」のいずれかになります。※ここで、算術シフトである「ア」は使えません。なぜなら最上位ビットは符号ビットではなく値として使いたいからです。
この反復処理では、最初に10進数の一の位(上位9~12ビット)、2回目に10進数の十の位(上位5~8ビット)、最後に10進数の百の位(上位1~4ビット)の加算を行っており、本来の位置に戻すためには、最初は4ビット、2回目は8ビット、3回目は12ビットの左シフトを行う必要があります。GR3 は、初期化部のコメントで「ビット数カウンタ」と説明されており、4で初期化されています。また、[c]の直後で4を加算しているので、ループの度に4→8→12というように増加していきます。これをシフトするビット数として用いるのが適切です(12ビット左シフト後に16になったらループ終了)。「ウ」のようにシフト数として固定値の4を使うと、どの加算結果も上位9~12ビット目に移された後 RESULT に退避され、次の桁との併合処理のときに上書きされることになってしまうので誤りです。∴c=イ:SLL GR1,0,GR3
広告
設問2
設問2の枝問fは問題誤りにつき,問12を選択した全員正解の措置済みです。
符号が異なる二つの16ビットのパック10進数を加算する副プログラム ADDP2 を作成した。プログラム2中の に入れる正しい答えを,解答群の中から選べ。ここで,プログラム2中のa,cには,設問1の正しい答えが入っているものとする。〔プログラム2の説明〕
- 副プログラム ADDP2 は,加算の対象となる符号が異なる二つの16ビットのパック10進数が,GR1,GR2に設定されて,呼び出される。
- 副プログラム ADDP2 は,加算結果をGROに設定して呼出し元に戻る。このとき,汎用レジスタ GR1~GR7 の内容は元に戻す。
d に関する解答群
- JMI INI
- JNZ INI
- JOV INI
- JPL INI
- JZE INI
e に関する解答群
- JMI MERGE
- JNZ MERGE
- JOV MERGE
- JZE MERGE
- SLL GR1,0,GR3
- SRL GR1,0,GR3
f に関する解答群
- ADDA GR1,GR0
- ADDL GR1,=1
- ADDL GR1,GR0
- ADDL GR3,GR0
- SUBL GR1,=1
- SUBL GR1,GR0
解答選択欄
- d:
- e:
- f:
- d=エ
- e=エ
- f=正解なし
解説
ADDP2は、「7 + (-5)」と「(-7) + 5」のように、符号の異なる値同士の加算を行うプログラムです。符号の異なる値同士を加算した結果の絶対値は「7 + (-5) = 2」「(-7) + 5 = (-2)」というように2値の絶対値の差ですから、本プログラムでは減算を用いています。〔dについて〕
符号の異なる値同士を加算した結果の符号は、2つの値のうち絶対値の大きい方の符号になります。符号部を退避させる RESULT には GR1 の下位4ビットが格納されるので、あらかじめ絶対値の大きい方の値が GR1 に入っているように調整しておく必要があります。
[d]の直前のCPL命令で GR1 と GR2 のビット列としての大小を確認し GR1<GR2 ならば、[d]以降の3行で値の交換を行っています。逆に、GR1≧GR2 のときには交換の必要がないのでラベルINIにジャンプさせなくてはなりません。GR1 と GR2 をCPL命令で比較したとき、GR1-GR2が非負であればSFが0となるので、このときJPL命令でラベルINIにジャンプさせることになります。
∴d=エ:JPL INI
- JMI だと GR1<GR2 のとき、すなわち値の交換をしなければならないときにジャンプしてしまいます。
- JNZ だと GR1<GR2 のときでもジャンプしてしまうので誤りです。
- CPL命令実行後のOFは常に0になります。つまり、GR1 と GR2 の大小にかかわらずジャンプせず、常に値の交換が行われてしまいます。
- 正しい。
- JZE だと GR1>GR2 のときでもジャンプしないので誤りです。
直後の命令で「ADDL GR1,=10」としており、ADDP1 のSUBL命令とは逆に10を加算しています。ADDP1 の動作を踏まえれば、ここは桁下がりが発生したときの処理であると推測できます。ADDP1 では GR1-GR2 が負数のときにJMI命令でジャンプさせていましたが、減算の場合には GR1-GR2 が0以上ならば桁下がりが発生しないので、JPL命令に加えてJZE命令を使い、GR1-GR2 が0のときにもラベルMERGEにジャンプさせる必要があります。
∴e=エ:JZE MERGE
- JMI だと桁下がりの処理を行うべき場合にジャンプしてしまうので誤りです。
- JNZ だと桁下がりの処理を行うべき場合にもジャンプしてしまうので誤りです。
- SUBL命令では結果が0~65535の範囲外となるとOFを1に設定します。桁下がりの処理を行うべき場合(GR1-GR2が負数のとき)にジャンプしてしまうので誤りです。
- 正しい。
- シフト演算を使うのは誤りです。
- シフト演算を使うのは誤りです。
問題不成立のため解説を割愛します。
広告
設問3
符号にかかわらず二つの16ビットのパック10進数を加算できるように,符号の組合せによって副プログラム ADDP1 と ADDP2 を使い分ける副プログラム ADDP を作成した。プログラム3中の に入れる正しい答えを,解答群の中から選べ。
〔プログラム3の説明)
〔プログラム3の説明)
- 副プログラム ADDP は,加算の対象となる二つの16ビットのパック10進数が,GR1,GR2に設定されて,呼び出される。
- 副プログラム ADDP の呼出し元に戻ったとき,加算結果は GR0 に入っている。
g に関する解答群
- ADDL GR1,=1
- AND GR0,GR2
- OR GR1,GR2
- SUBL GR1,=1
- XOR GR0,GR2
h に関する解答群
- JMI P2
- JNZ P2
- JOV P2
- JPL P2
- JZE P2
解答選択欄
- g:
- h:
- g=オ
- h=ウ
解説
ADDPは、同一の符号同士の加算を行う ADDP1 と異なる符号同士の加算を行う ADDP2 の使い分け(呼び分け)を行うプログラムです。〔gについて〕
〔プログラム1の説明〕にあるように、符号部は正の場合は"1100"、負の場合は"1101"で、最下位の1ビットが異なるだけです。そこで、GR1 と GR2 の下位4ビットの値をそのまま比較したいところですが、ADDP1 と ADDP2 は、GR1 と GR2 に値を設定して呼び出す仕様なので、ここで直接書き換えることはできません。
そのため、一旦 GR0 に GR1 のデータをロードした後に、GR0 と GR2 で比較を行います。最下位ビットが同じであるか異なっているかを判別したいのですから、2つのデータをXOR演算で抽出する「オ」が正解です。このとき、最下位ビットが異なっていれば、GR0 の最下位ビットは1となり、同じであれば0となります。
∴g=オ:XOR GR0,GR2
〔hについて〕
最下位ビットに符号の同異が設定された GR0 をSRL命令で右に1ビット論理シフトさせると、OFに GR0 から追い出されたビットの値(=GR0の最下位ビット)が入ります。これを使って0(符号が同じ)のときは ADDP1 を、1(符号が異なる)のときは ADDP2 に振り分けることが可能です。
ジャンプ先のラベルP2で呼び出されるプログラムは ADDP2 ですから、OFが1のときにジャンプするJOV命令を用いるのが適切です。
∴h=ウ:JOV P2
広告
広告