戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

基本情報技術者 2019年 春期 午後 問12


次のアセンブラプログラムの説明及びプログラムを読んで、設問1,2に答えよ。

〔プログラムの説明〕  主記憶上の連続した語から成る領域(以下、ビット領域という)内において、指定されたビット列(以下、対象ビット列という)に対する操作を行うための副プログラム群である。  対象ビット列は、連続したビットの並びであり、開始位置(以下、ビット位置という)とビット数(以下、ビット長という)で表す。ビット位置は、ビット領域全体を連続したビット列と捉えて、ビット領域の最初の語の最上位ビットを0ビット目としたときの相対位置である。対象ビット列はビット領域内に収まるものとする。  図1に、ビット領域及び対象ビット列(網掛け部分)の例を示す。ビット位置が44でビット長が24の場合、ビット領域の最初の語を0語目としたとき、対象ビット列の最初のビットを含む語は、2語目なので、これを相対アドレス2と表す。対象ビット列の最初のビットは、相対アドレス2の語の最上位ビットを0ビット目としたとき、12ビット目なので、この位置をビットインデックス12と表す。対象ビット列の最後のビットの位置を、相対アドレス4の語のビットインデックス3と表す。
基本情報技術者試験(令和元年 午後 問12 図1)
(1) プログラム1は、対象ビット列の全ビットを1にする副プログラムBITSONである。主プログラムは、連続した3語に、ビット領域の先頭アドレス、対象ビット列のビット位置、及び対象ビット列のビット長をこの順に格納して、その3語の先頭アドレスをGR1に設定して呼び出す。ビット位置及びビット長は、符号のない数値である。ビット長が0の場合は、対象ビット列に対する操作は行わない。 (2) プログラム2は、GR0で与えるビットマスクの値とビット領域内で操作の対象となる1語の値との論理和を求め、結果を同じ語に格納する副プログラムSETOPである。GR0に1語内のビット操作の対象となるビットを1で表すビットマスクを、GR1にビット領域の先頭アドレスを格納した語のアドレスを、GR2に操作の対象となる語への相対アドレスを設定して、呼び出される。 (3) 副プログラムから戻るとき、汎用レジスタGR1〜GR7の内容は元に戻す。
基本情報技術者試験(令和元年 午後 問12 プログラム1)
基本情報技術者試験(令和元年 午後 問12 プログラム2)

設問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:カ

解説

解答の導き方

この問題では、対象ビット列が語の途中から始まったり、複数の語にまたがったりする場合に、対象のビットだけを1にする方法を考えます。
語は、ここでは16ビットをひとまとめにしたものです。レジスタは、計算中の値を一時的に入れておく場所です。
  1. ビット位置を、相対アドレスとビットインデックスに分けます
    プログラムでは、まずGR3にビット位置を読み込み、GR2にも同じ値を入れています。ビット領域の1語は16ビットなので、ビット位置を16で割った商が相対アドレス、余りがビットインデックスになります。
    例えば、図1のビット位置44は、 余り12です。つまり、相対アドレスは2、ビットインデックスは12です。
    GR2を4ビット右へ論理シフトすると、16で割った商になります。論理シフトとは、ビット列を左右にずらし、空いた位置に0を入れる操作です。一方、GR3に「#000F」との論理積を取ると、下位4ビットだけが残り、16で割った余りになります。
    したがって、aにはGR2を4ビット右へずらす「SRL GR2,4」が入ります。解答群ではオです。
  2. 現在の語で操作するビット数を求めます
    GR3は現在の語の中での開始位置、GR4は残りのビット長です。プログラムはGR3とGR4を足し、その合計が16未満なら対象ビット列が語の境界を越えないと判断します。16以上なら、現在の語の末尾までを処理します。
    GR5にはまず16が入ります。開始位置が0でなければ、現在の語の末尾までのビット数は「16 − ビットインデックス」です。そこでGR5からGR3を引きます。bは「SUBL GR5,GR3」となり、解答群ではオです。
    この後、GR4からGR5を引きます。これにより、処理した分だけ残りのビット長が減ります。GR3は0にされるので、次の語ではその先頭から処理できます。
  3. 現在の語の対象ビットを1にするマスクを作ります
    GR5が操作するビット数です。1をGR5ビット左へずらしてから1を引くと、下位側にGR5個の1が並ぶマスクになります。例えば、GR5が4なら、マスクは「#000F」です。
    ビットインデックスは語の最上位ビットを0として数えます。そのため、開始位置が12なら、語の末尾までの4ビットは語の下位4ビットに当たります。このマスクをSETOPに渡すと、対象の4ビットを1にできます。
    開始位置が0の場合は、語全体の16ビットを操作します。このときGR5は16のままで、マスクは語全体が1になります。
  4. 残りのビットがなければ終了します
    語の境界までの処理を終えた後、GR4には未処理のビット長が残ります。「LD GR4,GR4」は値を変えずに、GR4が0かどうかを判定するための処理です。
    GR4が0なら、追加で操作するビットはありません。そこでcには、GR4が0のときFINへ進む「JZE FIN」が入ります。解答群ではオです。
  5. 最後に残ったビットの位置にマスクを合わせます
    GR4が0でなければ、残りのビットは現在の語の中に収まっています。まず、GR4個の1が下位側に並ぶマスクを作ります。
    このマスクを対象の位置に合わせるには、左へずらすビット数を求めます。GR5には「16 − GR3」が入るので、そこから残りのビット長GR4を引くと、マスクのシフト量は
    となります。したがって、dには「SUBL GR5,GR4」が入り、解答群ではカです。
    例えば、ビット位置44、ビット長24の場合は、相対アドレス2のビットインデックス12から始まります。最初の語では末尾までの4ビットを操作し、次の語では16ビット全体を操作します。残りの4ビットは相対アドレス4の先頭にあるため、マスクを12ビット左へずらして位置を合わせます。

誤りやすいポイント

  • ビット位置を16で割った商が相対アドレス、余りがビットインデックスです。4ビット右シフトで商を求め、下位4ビットを残して余りを求めます。
  • ビットインデックスは最上位ビットから数えます。そのため、語の末尾側のビットを操作するマスクは、下位側に並びます。
  • bとdはどちらも減算ですが、目的が異なります。bは語の末尾までに操作するビット数を求め、dは最後のマスクを左へずらす量を求めます。
  • GR4が0のときは、残りのビットがありません。追加のマスクを作らず、FINへ進みます。

FAQ

Q: なぜ1語を16ビットとして計算するのですか?
A: プログラム中で「BITSPW DC 16」と定義されており、1語のビット数を16として扱っているためです。ビット位置を16で割ると、語の位置と語の中の位置に分けられます。
Q: SETOPは、対象外のビットも変更しますか?
A: SETOPは、対象の語とビットマスクの論理和を取ります。論理和では、マスクが0のビットは元の値が保たれ、マスクが1のビットは1になります。そのため、対象外のビットは変更されません。
Q: なぜ対象ビット列を語ごとに分けて処理するのですか?
A: 対象ビット列は、語の途中から始まったり、複数の語にまたがったりするためです。最初の語の残り、途中にある語全体、最後の語の一部分に分けると、それぞれに合ったマスクを作れます。

関連キーワード: ビットマスク、論理シフト、論理和、相対アドレス、ビットインデックス

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

 次の記述中のに入れる正しい答えを、解答群の中から選べ。    対象ビット列の全ビットを0にする副プログラムを新規に作成することを考える。  ビット領域内の操作の対象になる語の相対アドレスやビットインデックスを求める処理などは、プログラム1で実装されている。そこで、新規の副プログラムを作成する前に、既存の副プログラム群を再編成し、対象ビット列の全ビットを1にする副プログラム及び0にする副プログラムが、プログラム1の処理を利用できるようにする。  プログラム1に変更を加え、それに伴って副プログラムBITSONを、その仕様は変更せずに再実装する方法を、次の(1)〜(3)に示す。   (1) 次に示すプログラム3を新たな副プログラムBITSON(以下、新BITSONという)とする。新BITSONは、既存の副プログラムSETOPのアドレスをGR7に設定して変更後のプログラム1を呼び出す。
基本情報技術者試験(令和元年 午後 問12 プログラム3)
(2) プログラム1の入口名を変更するために、行番号1のラベルをeにする。 (3) プログラム1の行番号24と行番号38のCALL命令のオペランドをfに変更する。    このように、既存の副プログラム群を再編成した後に、対象ビット列の全ビットを0にする処理のための副プログラムBITSOFF(プログラムは省略)と、それが変更後のプログラム1を介して呼び出す副プログラムRESETOP(プログラムは省略)を作成する。二つの副プログラムの概要を、次の(1)、(2)に示す。   (1) 副プログラムBITSOFFは、新BITSONと同様に、副プログラムRESETOPのアドレスをGR7に設定して副プログラムBITSOPを呼び出す。 (2) 副プログラム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:オ

解説

解答の導き方

この問題では、ビット列の位置を調べる処理はそのまま使い、最後にビットを操作する処理だけを切り替えられるようにします。
1語は16ビットです。プログラム1は、対象ビット列が1語に収まらない場合も、語ごとに分けて処理します。そのため、まず操作する語の相対アドレスやビットインデックスを求め、次にその語のどのビットを操作するかをビットマスクで表します。ビットマスクは、操作したいビットを1で示す値です。
元のプログラム1では、語ごとにビットマスクを作った後、行番号24と行番号38でSETOPを呼び出します。SETOPは、GR0のビットマスクと対象の語との論理和(どちらかが1なら結果を1にする演算)を取り、結果を同じ語に格納します。これにより、マスクで示したビットが1になります。
ここで、位置を探してマスクを作る部分と、実際にビットを操作する部分を分けます。位置を探してマスクを作る部分をBITSOPとして共通化し、どの操作を行うかはGR7に設定した副プログラムに任せます。
eはBITSOPです。 プログラム3では、GR7にSETOPのアドレスを設定した後、BITSOPを呼び出しています。したがって、プログラム1の入口名をBITSOPにすれば、プログラム3から位置計算やマスク生成の処理を呼び出せます。プログラム1の行番号1のラベルは、BITSOPに変更します。
fは0,GR7です。 GR7には、呼び出す副プログラムのアドレスが入っています。CALL 0,GR7は、GR7に格納されたアドレスを使って副プログラムを呼び出す指定です。先頭の0はアドレスに加える値で、実際に呼び出す先はGR7の内容になります。したがって、行番号24と行番号38のCALL命令のオペランドを、どちらも0,GR7に変更します。
この変更により、新BITSONはGR7にSETOPのアドレスを設定してBITSOPを呼び出します。BITSOPが語ごとに操作を行うとき、GR7のアドレスを使ってSETOPが呼び出されるため、対象ビット列を1にできます。
同じ仕組みで、BITSOFFはGR7にRESETOPのアドレスを設定してBITSOPを呼び出します。RESETOPは、ビットマスクの0と1を反転した値と対象の語との論理積(両方が1の場合だけ1にする演算)を取ります。操作対象のビットは、反転したマスクで0になるので結果も0になります。一方、操作対象ではないビットは、反転したマスクで1になるので元の値が保たれます。これで、対象ビット列だけを0にできます。

誤りやすいポイント

  • プログラム1の入口名と、ビット操作を行う副プログラムの名前を混同しないようにします。 プログラム1は位置計算などを行う共通処理なので、入口名をBITSOPに変更します。
  • SETOPを呼び出す箇所は2か所あります。 行番号24だけでなく、行番号38のCALL命令も変更しないと、処理するビット列の一部で指定した副プログラムが使われません。
  • GR7に設定するのは、呼び出す副プログラムのアドレスです。 GR5はプログラム1で操作するビット数に使われるため、呼出し先を指定するレジスタには使いません。
  • 0,GR7はGR7を使って呼び出し先を切り替える指定です。 ここをSETOPなどの固定名にすると、BITSOFFから呼び出した場合にもSETOPが実行されてしまいます。

FAQ

Q: プログラム1の中で、SETOPを直接呼び出す形のままではいけませんか?
A: そのままでは、BITSOPをBITSONとBITSOFFの両方から共通利用できません。GR7を使って呼出し先を選ぶことで、同じ位置計算とマスク生成の処理からSETOPまたはRESETOPを呼び出せます。
Q: なぜSETOPとRESETOPで、同じビットマスクを使えるのですか?
A: SETOPはマスクの1に対応するビットを1にします。RESETOPはマスクを反転してから論理積を取るため、マスクの1に対応するビットを0にし、それ以外のビットは保ちます。
Q: GR7の内容は、BITSOPから戻った後も保たれますか?
A: 問題文では、副プログラムから戻るときにGR1〜GR7の内容を元に戻すとあります。したがって、BITSOPやSETOPから戻った後も、GR7に設定した呼出し先のアドレスを利用できます。

関連キーワード: ビットマスク、論理演算、サブルーチン、レジスタ、間接アドレス指定

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

戦国ITクイズ機能

\ せっかくなら /

基本情報技術者を
クイズ形式で学習しませんか?

クイズ画面へ遷移する→

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について