HOME»基本情報技術者平成31年春期問題»午後問12
基本情報技術者過去問題 平成31年春期 午後問12
⇄問題文と設問を画面2分割で開く⇱問題PDF⇱アセンブラ言語の仕様問12 ソフトウェア開発(アセンブラ)
次のアセンブラプログラムの説明及びプログラムを読んで,設問1,2に答えよ。
〔プログラムの説明〕
主記憶上の連続した語から成る領域(以下,ビット領域という)内において,指定されたビット列(以下,対象ビット列という)に対する操作を行うための副プログラム群である。
対象ビット列は,連続したビットの並びであり,開始位置(以下,ビット位置という)とビット数(以下,ビット長という)で表す。ビット位置は,ビット領域全体を連続したビット列と捉えて,ビット領域の最初の語の最上位ビットを0ビット目としたときの相対位置である。対象ビット列はビット領域内に収まるものとする。
図1に,ビット領域及び対象ビット列(網掛け部分)の例を示す。ビット位置が44でビット長が24の場合,ビット領域の最初の語を0語目としたとき,対象ビット列の最初のビットを含む語は,2語目なので,これを相対アドレス2と表す。対象ビット列の最初のビットは,相対アドレス2の語の最上位ビットを0ビット目としたとき,12ビット目なので,この位置をビットインデックス12と表す。対象ビット列の最後のビットの位置を,相対アドレス4の語のビットインデックス3と表す。
〔プログラムの説明〕
主記憶上の連続した語から成る領域(以下,ビット領域という)内において,指定されたビット列(以下,対象ビット列という)に対する操作を行うための副プログラム群である。
対象ビット列は,連続したビットの並びであり,開始位置(以下,ビット位置という)とビット数(以下,ビット長という)で表す。ビット位置は,ビット領域全体を連続したビット列と捉えて,ビット領域の最初の語の最上位ビットを0ビット目としたときの相対位置である。対象ビット列はビット領域内に収まるものとする。
図1に,ビット領域及び対象ビット列(網掛け部分)の例を示す。ビット位置が44でビット長が24の場合,ビット領域の最初の語を0語目としたとき,対象ビット列の最初のビットを含む語は,2語目なので,これを相対アドレス2と表す。対象ビット列の最初のビットは,相対アドレス2の語の最上位ビットを0ビット目としたとき,12ビット目なので,この位置をビットインデックス12と表す。対象ビット列の最後のビットの位置を,相対アドレス4の語のビットインデックス3と表す。
- プログラム1は,対象ビット列の全ビットを1にする副プログラム BITSON である。主プログラムは,連続した3語に,ビット領域の先頭アドレス,対象ビット列のビット位置,及び対象ビット列のビット長をこの順に格納して,その3語の先頭アドレスを GR1 に設定して呼び出す。ビット位置及びビット長は,符号のない数値である。ビット長が0の場合は,対象ビット列に対する操作は行わない。
- プログラム2は,GR0 で与えるビットマスクの値とビット領域内で操作の対象となる1語の値との論理和を求め,結果を同じ語に格納する副プログラム SETOP である。GR0 に1語内のビット操作の対象となるビットを1で表すビットマスクを,GR1 にビット領域の先頭アドレスを格納した語のアドレスを,GR2 に操作の対象となる語への相対アドレスを設定して,呼び出される。
- 副プログラムから戻るとき,汎用レジスタ GR1~GR7 の内容は元に戻す。
設問1
プログラム中の に入れる正しい答えを,解答群の中から選べ。
a に関する解答群
- SLL GR2,0,GR3
- SLL GR2,4
- SLL GR2,4,GR3
- SRL GR2,0,GR3
- SRL GR2,4
- SRL GR2,4,GR3
b,d に関する解答群
- ADDL GR5,GR2
- ADDL GR5,GR3
- ADDL GR5,GR4
- SUBL GR5,GR2
- SUBL GR5,GR3
- SUBL GR5,GR4
c に関する解答群
- JNZ FIN
- JNZ LOOP
- JPL FIN
- JPL LOOP
- JZE FIN
- JZE LOOP
解答選択欄
- a:
- b:
- c:
- d:
解答
- a=オ
- b=オ
- c=オ
- d=カ
解説
〔aについて〕
4,5行目のコメントにあるように、7,8行で GR2 と GR3 に格納されているビット位置から相対アドレスとビットインデックスを求めています。問題文の例で、ビット位置が44のときの相対アドレスが2、ビットインデックスが12と説明されているのを参考にし、図1を見ながら一般化すると、というように、相対アドレスはビット番号を16で割った商、ビットインデックスは余りになることがわかります。さらに、それぞれを16進数で表すと、というように、ビット番号の上位12ビット部分がそのまま相対アドレスを示し、下位4ビット部分がそのままビットインデックスになっています。8行目で、GR3 の下位4ビットをANDで取り出す操作がビットインデックスを求める処理ですので、[a]には相対アドレスを求める処理が入ります。ビット番号から相対アドレスを求めるには、ビット番号を右に4ビット論理シフトする操作を行うのが適切です。
∴a=オ:SRL GR2,4
〔bについて〕
直前のJZE命令で GR3 が0のときにはラベルFULLに分岐しています。よって、[b]に入るのは GR3 が0ではないときの処理です。
GR3 はビットインデックスを保持していて、この値が0ということは、当該アドレスの0番目から1にするビット列が始まることを示しています。しかし、対象ビット列の範囲は、図1のビット位置のように必ずしも当該アドレスの0番目のビットから始まるとは限りません(特に最初のアドレスは)。そこで、ビットインデックスが0ではないときには、GR5(語内で対象となるビット数:初期値16)を調整しておく必要があります。
先程と同様に、ビットインデックス12を例にすると、1語16ビットの中で1にするビット数は(12~15の)4つです。これは16からビットインデックスを保持する GR3 を引くことで求められます。GR5 には定数 BITSPW(=16)が格納されていますから、GR5 から GR3 を引くSUBL命令が適切となります。次のアドレスからは0番目から始まるので、その後19行目では GR3 に0を格納しています。
∴b=オ:SUBL GR5,GR3
〔cについて〕
ラベルBREAKにジャンプするのは、13行目の比較で GR0 が16未満となったときです。ラベルBREAKでは、GR4 にLD命令を行ってフラグレジスタを設定し、その値によって分岐させています。コメント部にあるように、この分岐は未処理のビットがあるかどうかを確認するためのものであり、未処理のビットがあるときには31行目以降の処理を実行することになっています(図1の相対アドレス4の部分)。GR4 は初期値としてビット長が格納され、その後、20行目で操作済みビットの数だけ減らされていきます。GR4 が0のときには未処理のビットがなく操作が完了しているので、JZE命令でラベルFINに分岐させ、プログラムを終了することになります。
∴c=オ:JZE FIN
〔dについて〕
31行目から38行目は、対象ビット列が存在する最後のアドレスに対して行う処理です。ここでは語内のビットのうち、残りビット数分だけをビットマスクを作成する処理が行われます。少しわかりづらいのですが、この部分が実行されるケースには以下の2パターンがあります。ビットマスクは操作対象のビットを1で表したものなので、上のパターンでは「1111 0000 0000 0000」、下のパターンでは「0011 1111 1111 1100」というビット列が GR0 に設定されればよいわけです。
プログラム上では31~33行目で、残りビット数分の右詰めのビットマスクを生成しています。上のパターンの場合だと残りビット数が4なので、以下の操作で右詰めのビットマスクを生成しています。このビットマスクの生成に必要なビット分だけ左にシフトさせることになります。残りビット数が4の場合に左に12ビットシフトさせると適切なビットマスクになることから、「16-残りビット数」が左シフトさせるビット数となります。37行目では GR5 の値だけ左にシフトさせていますので、BITSPW(=16)が格納されている GR5 から、残りビット数が格納されている GR4 の値を引くSUBL命令が適切となります。
なお、35行目の GR5 - GR3 の処理は、上記の下のパターンのときに必要となります。この場合は、16からビットインデックスと残りビット数を両方引くことで適切なシフト数が求められます(16-2-12=2)。上のパターンのときには GR3 が0になっているので GR5 は16のままです。
∴d=カ:SUBL GR5,GR4
4,5行目のコメントにあるように、7,8行で GR2 と GR3 に格納されているビット位置から相対アドレスとビットインデックスを求めています。問題文の例で、ビット位置が44のときの相対アドレスが2、ビットインデックスが12と説明されているのを参考にし、図1を見ながら一般化すると、というように、相対アドレスはビット番号を16で割った商、ビットインデックスは余りになることがわかります。さらに、それぞれを16進数で表すと、というように、ビット番号の上位12ビット部分がそのまま相対アドレスを示し、下位4ビット部分がそのままビットインデックスになっています。8行目で、GR3 の下位4ビットをANDで取り出す操作がビットインデックスを求める処理ですので、[a]には相対アドレスを求める処理が入ります。ビット番号から相対アドレスを求めるには、ビット番号を右に4ビット論理シフトする操作を行うのが適切です。
∴a=オ:SRL GR2,4
〔bについて〕
直前のJZE命令で GR3 が0のときにはラベルFULLに分岐しています。よって、[b]に入るのは GR3 が0ではないときの処理です。
GR3 はビットインデックスを保持していて、この値が0ということは、当該アドレスの0番目から1にするビット列が始まることを示しています。しかし、対象ビット列の範囲は、図1のビット位置のように必ずしも当該アドレスの0番目のビットから始まるとは限りません(特に最初のアドレスは)。そこで、ビットインデックスが0ではないときには、GR5(語内で対象となるビット数:初期値16)を調整しておく必要があります。
先程と同様に、ビットインデックス12を例にすると、1語16ビットの中で1にするビット数は(12~15の)4つです。これは16からビットインデックスを保持する GR3 を引くことで求められます。GR5 には定数 BITSPW(=16)が格納されていますから、GR5 から GR3 を引くSUBL命令が適切となります。次のアドレスからは0番目から始まるので、その後19行目では GR3 に0を格納しています。
∴b=オ:SUBL GR5,GR3
〔cについて〕
ラベルBREAKにジャンプするのは、13行目の比較で GR0 が16未満となったときです。ラベルBREAKでは、GR4 にLD命令を行ってフラグレジスタを設定し、その値によって分岐させています。コメント部にあるように、この分岐は未処理のビットがあるかどうかを確認するためのものであり、未処理のビットがあるときには31行目以降の処理を実行することになっています(図1の相対アドレス4の部分)。GR4 は初期値としてビット長が格納され、その後、20行目で操作済みビットの数だけ減らされていきます。GR4 が0のときには未処理のビットがなく操作が完了しているので、JZE命令でラベルFINに分岐させ、プログラムを終了することになります。
∴c=オ:JZE FIN
〔dについて〕
31行目から38行目は、対象ビット列が存在する最後のアドレスに対して行う処理です。ここでは語内のビットのうち、残りビット数分だけをビットマスクを作成する処理が行われます。少しわかりづらいのですが、この部分が実行されるケースには以下の2パターンがあります。ビットマスクは操作対象のビットを1で表したものなので、上のパターンでは「1111 0000 0000 0000」、下のパターンでは「0011 1111 1111 1100」というビット列が GR0 に設定されればよいわけです。
プログラム上では31~33行目で、残りビット数分の右詰めのビットマスクを生成しています。上のパターンの場合だと残りビット数が4なので、以下の操作で右詰めのビットマスクを生成しています。このビットマスクの生成に必要なビット分だけ左にシフトさせることになります。残りビット数が4の場合に左に12ビットシフトさせると適切なビットマスクになることから、「16-残りビット数」が左シフトさせるビット数となります。37行目では GR5 の値だけ左にシフトさせていますので、BITSPW(=16)が格納されている GR5 から、残りビット数が格納されている GR4 の値を引くSUBL命令が適切となります。
なお、35行目の GR5 - GR3 の処理は、上記の下のパターンのときに必要となります。この場合は、16からビットインデックスと残りビット数を両方引くことで適切なシフト数が求められます(16-2-12=2)。上のパターンのときには GR3 が0になっているので GR5 は16のままです。
∴d=カ:SUBL GR5,GR4
設問2
次の記述中の に入れる正しい答えを,解答群の中から選べ。
対象ビット列の全ビットを0にする副プログラムを新規に作成することを考える。
ビット領域内の操作の対象になる語の相対アドレスやビットインデックスを求める処理などは,プログラム1で実装されている。そこで,新規の副プログラムを作成する前に,既存の副プログラム群を再編成し,対象ビット列の全ビットを1にする副プログラム及び0にする副プログラムが,プログラム1の処理を利用できるようにする。
プログラム1に変更を加え,それに伴って副プログラム BITSON を,その仕様は変更せずに再実装する方法を,次の(1)~(3)に示す。
対象ビット列の全ビットを0にする副プログラムを新規に作成することを考える。
ビット領域内の操作の対象になる語の相対アドレスやビットインデックスを求める処理などは,プログラム1で実装されている。そこで,新規の副プログラムを作成する前に,既存の副プログラム群を再編成し,対象ビット列の全ビットを1にする副プログラム及び0にする副プログラムが,プログラム1の処理を利用できるようにする。
プログラム1に変更を加え,それに伴って副プログラム BITSON を,その仕様は変更せずに再実装する方法を,次の(1)~(3)に示す。
- 次に示すプログラム3を新たな副プログラム BITSON (以下,新BITSONという)とする。新BITSON は,既存の副プログラム SETOP のアドレスを GR7 に設定して変更後のプログラム1を呼び出す。
- プログラム1の入口名を変更するために,行番号1のラベルをeにする。
- プログラム1の行番号24と行番号38の CALL 命令のオペランドをfに変更する。
- 副プログラム BITSOFF は,新BITSON と同様に,副プログラム RESETOP のアドレスを GR7 に設定して副プログラム BITSOP を呼び出す。
- 副プログラム RESETOP は,副プログラム SETOP と同様のインタフェースで呼び出される。GR0 には,1語内でビット操作の対象になるビットを表すビットマスクが設定されているので,GR0 の全ビットについて0と1を反転させた値と,GR1 と GR2 とで指定された語の値との論理積を求め,結果を同じ語に格納する。
e に関する解答群
- BITSON
- BITSOP
- SETOP
f に関する解答群
- 0,GR5
- BITSON,GR5
- 0,GR6
- BITSON,GR6
- 0,GR7
- BITSON,GR7
解答選択欄
- e:
- f:
解答
- e=イ
- f=オ
解説
〔eについて〕
新 BITSON では、内部で BITSOP が呼び出されプログラム1の処理が行われると説明しています。CALL BITSOP によってプログラム1が呼び出されるためには、プログラム1のプログラム名(行番号1のラベル)を BITSOP に変更する必要があります。
∴e=イ:BITSOP
〔fについて〕
問題文の説明を読むと、新BITSON と BITSOFF でプログラム1を共用し、ビット操作を行う SETOP と RESETOP の呼び分けだけで2つの処理を実装をしようとしていることがわかります。新BITSON の3行目で GR7 に SETOP のアドレスが格納されているように、BITSOFF でも GR7 に RESETOP のアドレスが格納されると判断できます。〔プログラム1〕では、呼出しプログラムが SETOP に固定されていますが、これを GR7 に格納されているプログラムを呼び出すように変更することで、BITSOP内で自動的に呼び分けされるようになります。
「ア」~「エ」は、副プログラムのアドレスが格納されている GR7 を使用していないので誤り、「カ」は BITSON のアドレスを副プログラムのアドレスで修飾していて意味不明なので誤りです。また、BITSON を含めているものは、BITSOFF の場合を想定していないので不適切です。
∴f=オ:0,GR7
新 BITSON では、内部で BITSOP が呼び出されプログラム1の処理が行われると説明しています。CALL BITSOP によってプログラム1が呼び出されるためには、プログラム1のプログラム名(行番号1のラベル)を BITSOP に変更する必要があります。
∴e=イ:BITSOP
〔fについて〕
問題文の説明を読むと、新BITSON と BITSOFF でプログラム1を共用し、ビット操作を行う SETOP と RESETOP の呼び分けだけで2つの処理を実装をしようとしていることがわかります。新BITSON の3行目で GR7 に SETOP のアドレスが格納されているように、BITSOFF でも GR7 に RESETOP のアドレスが格納されると判断できます。〔プログラム1〕では、呼出しプログラムが SETOP に固定されていますが、これを GR7 に格納されているプログラムを呼び出すように変更することで、BITSOP内で自動的に呼び分けされるようになります。
「ア」~「エ」は、副プログラムのアドレスが格納されている GR7 を使用していないので誤り、「カ」は BITSON のアドレスを副プログラムのアドレスで修飾していて意味不明なので誤りです。また、BITSON を含めているものは、BITSOFF の場合を想定していないので不適切です。
∴f=オ:0,GR7