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

基本情報技術者 2017年 秋期 午後 問12


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

〔プログラム1の説明〕  連続する2語から成るビット列αの中から、別のビット列βと一致する部分ビット列を検索する副プログラムBSRHである。部分ビット列の検索の概要を、図1に示す。
基本情報技術者試験(平成29年 午後 問12 図1)
(1) 主プログラムは、αが格納されている領域の先頭アドレスをGR1に、βをGR2に、βの長さn (1≦n≦16)をGR3に設定して副プログラムBSRHを呼ぶ。βはGR2に左詰めで設定し、残りのビットには0を設定する。 (2) 副プログラムBSRHは、αの先頭(ビット位置0)からβと照合し、一致する部分ビット列がある場合は最初に一致する部分ビット列の先頭のビット位置pを、一致する部分ビット列がない場合は−1を、GR0に設定して主プログラムに戻る。 (3) 副プログラムBSRHから戻るとき、汎用レジスタGR1~GR7の内容は元に戻す。
基本情報技術者試験(平成29年 午後 問12 プログラム1)

設問1:

問題文を見る
 プログラム1中のに入れる正しい答えを、解答群の中から選べ。   aに関する解答群  ア:AND GR7,GR2  イ:OR GR7,GR2  ウ:SLL GR7,0,GR2  エ:SRL GR7,0,GR2  オ:XOR GR7,GR2   bに関する解答群  ア:JMI FOUND  イ:JMI NEXT  ウ:JOV FOUND  エ:JOV NEXT  オ:JPL FOUND  カ:JPL NEXT

模範解答

a:オ、b:エ

解説

解答の導き方

設問は、現在の候補部分ビット列とβを比べる処理aと、候補を1ビットずつ進める処理bを選ぶ問題です。
まず、aで比較に使う値を確認します。GR6には、βの長さに合わせたマスク(必要なビットだけを取り出すための値)を作っています。GR6の初期値は#FFFFで、16ビットすべてが1です。これをビット右にずらしてから反転するため、最終的にGR6の左側ビットが1、それ以外が0になります。
12行目のLD GR7,GR4で、現在の候補位置にあるαの先頭部分をGR7にコピーします。13行目のAND GR7,GR6でマスクを適用すると、GR7には候補部分の先頭ビットだけが残り、それ以外のビットは0になります。
問題文には「βはGR2に左詰めで設定し、残りのビットには0を設定する」とあります。つまり、GR7とGR2は、比較するビットが同じ位置にあり、残りのビットはどちらも0です。ここで使うのは、異なるビットを1にするXOR(Exclusive OR:排他的論理和)です。GR7とGR2に違いがなければ、XORの結果はすべて0になります。その直後にJZE FOUNDがあるので、結果が0なら一致したと判断できます。
したがって、aにはGR7とGR2をXORで比較する命令が入り、解答群のオになります。
次に、bでαを次の候補位置に進める方法を確認します。αはGR4とGR5の2語に分けて格納されています。候補を1ビット進めるため、18行目と19行目でGR4とGR5をそれぞれ左に1ビットずらしています。このようにビットを左右にずらす操作を論理シフトといいます。
ただし、2つの語を別々にシフトするだけでは、GR5の左端にあったビットが失われます。そのビットは、シフト後のGR4の右端に移す必要があります。GR5を左にずらしたとき、左端から外へ出たビットが1ならオーバフローフラグ(シフトで外へ出たビットが1だったことを示す情報)が立ちます。そこで、GR5をシフトした後にJOV NEXTで分岐し、フラグが立っている場合だけNEXTのOR GR4,=#0001を実行します。これにより、GR4の右端に1を設定できます。
したがって、bには「オーバフローフラグが立っているときにNEXTへ進む」命令が入り、解答群のエです。
なお、GR1は候補位置を進めるたびに1ずつ減ります。最初に候補位置0を調べ、最後の候補位置まで調べても一致しなければ、GR1が負になってJMI FINへ進みます。一致した場合は、元のGR1の値を保持しているGR3から現在のGR1を引くことで、先頭から何ビット進んだ位置かを求めています。

誤りやすいポイント

  • aでは、ANDで候補部分を取り出す処理と、βとの一致を判定する処理を区別します。ANDは候補部分を抜き出すためにすでに13行目で使われています。一致判定には、違いがあると1になるXORを使います。
  • βの長さがビットでも、GR2の残りのビットは0です。そのため、候補側もマスクで不要なビットを0にしてから比べます。
  • bのJOVが判断するのは、直前のGR5の左シフトで外へ出たビットです。GR4の左シフトで出たビットではありません。
  • JMIは負かどうかを調べる命令、JOVはオーバフローフラグが立っているかを調べる命令です。役割を混同しないようにします。

FAQ

Q: なぜ候補部分をマスクした後で、さらにβと比べるのですか?
A: マスクは、αから比較に使うビットだけを取り出す処理です。その取り出したビットがβと一致するかどうかは、別途XORで調べます。
Q: XORの結果が0になるのは、どのようなときですか?
A: 対応するビットがすべて同じときです。同じビット同士をXORすると0になるため、全体の結果が0なら候補部分とβが一致しています。
Q: GR5の左シフトで外へ出たビットを、なぜGR4に加えるのですか?
A: GR4とGR5をつなげて1つの32ビット列として扱うためです。GR5の左端にあったビットは、シフト後にGR4の右端へ移る必要があります。

関連キーワード: ビットマスク、排他的論理和、論理シフト、オーバフローフラグ、部分ビット列検索

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

この設問をAIに質問する

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

 プログラム1の行番号4~6を、次の2命令で置き換えても、GR6には同じ値が得られる。に入れる正しい答えを、解答群の中から選べ。
  LD  GR6,=#8000      解答群  ア:SLL GR6,-1,GR3  イ:SLL GR6,0,GR3  ウ:SRA GR6,-1,GR3  エ:SRA GR6,0,GR3  オ:SRL GR6,-1,GR3  カ:SRL GR6,0,GR3

模範解答

ウ

解説

解答の導き方

この設問では、行番号4~6の処理と同じ値をGR6に作る命令を選びます。まず、GR6に作る値がどのようなビット列なのかを確認します。
プログラムでは、後で「AND GR7,GR6」を実行します。GR2に設定されたβは左詰めなので、GR6にはβの長さに合わせて、左端から個が1で、残りが0のマスクを作る必要があります。マスクとは、ビット演算で必要な部分だけを取り出すためのビット列です。
行番号4~6では、次の手順でこのマスクを作っています。
  • 「LD GR6,=#FFFF」で、GR6を16個の1で埋めます。
  • 行番号5の「SRL GR6,0,GR3」で、GR3に入っているだけ右へ論理シフトします。SRL(Shift Right Logical:空いた左側を0で埋める右シフト)なので、左側に個の0ができます。
  • 行番号6の「XOR GR6,=#FFFF」で、全ビットを反転します。XOR(Exclusive OR:排他的論理和)は、相手が1のビットを反転させる演算です。
たとえばの場合は、次のようになります。
  • シフト前:1111111111111111
  • 右へ5ビットシフトした後:0000011111111111
  • 全ビットを反転した後:1111100000000000
つまり、GR6には左から個の1が並ぶ値が入ります。
選択肢の命令では、GR6に「=#8000」を設定します。これは、16ビットで表すと「1000000000000000」です。先頭のビットだけが1です。
ここで、SRA(Shift Right Arithmetic:符号を保つ右シフト)を使うと、右へシフトしたときに空いた左側へ、先頭のビットである1が補われます。命令「SRA GR6,-1,GR3」では、シフト数はです。GR3にはが入っているので、シフト数はになります。
先頭にある1個の1に加えて、左側へ個の1が補われます。その結果、先頭から個が1のマスクになります。これは行番号4~6で作る値と同じです。たとえばなら、4ビット右へ算術シフトして「1111100000000000」になります。
したがって、空欄には「SRA GR6,-1,GR3」を入れます。これは解答群のウです。

誤りやすいポイント

  • SRAとSRLを取り違えないようにします。SRAは左端のビットを補い、SRLは左側を0で埋めます。今回は左端の1を増やす必要があるため、SRAを使います。
  • GR3にはが入っているため、シフト数をにすると1が個になります。必要なシフト数はです。
  • 「=#8000」は1個だけ1のビット列です。最初からマスクが完成しているのではなく、算術シフトで必要な数の1を増やします。

FAQ

Q: なぜシフト数がではなくなのですか?
A: 「=#8000」の時点で、すでに先頭に1が1個あります。そこへ個の1を補えば、合計で個になります。
Q: SRLを使って右へシフトすると、なぜ同じ結果にならないのですか?
A: SRLは左側を0で埋めるため、先頭に1を増やせません。今回必要なのは、先頭の1を保ちながら左側へ1を補う処理です。
Q: 作ったマスクはβそのものですか?
A: βそのものではありません。後続のAND演算で、αのうちβと照合する部分を取り出すために使います。

関連キーワード: ビット演算、論理シフト、算術シフト、マスク、排他的論理和

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

この設問をAIに質問する

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

 αの先頭からβと照合し、最初に一致する部分ビット列を、βと同じ長さの別のビット列γで置き換える副プログラムBREPを、副プログラムBSRHを使用して作成した。γはGR4に左詰めで設定し、残りのビットには0を設定する。それ以外のBREPの呼出しに関する仕様は、プログラム1の説明中のBSRHをBREPに読み替えて適用する。プログラム2中のに入れる正しい答えを、解答群の中から選べ。
基本情報技術者試験(平成29年 午後 問12 プログラム2)
cに関する解答群  ア:ADDL GR2,GR7  イ:LD GR2,=0  ウ:LD GR2,=16  エ:LD GR2,=32  オ:SUBA GR2,GR7   dに関する解答群  ア:AND GR2,GR4  イ:OR GR2,GR4  ウ:SLL GR2,0,GR4  エ:SRL GR2,0,GR4  オ:XOR GR2,=#FFFF

模範解答

c:イ、d:イ

解説

解答の導き方

まず、BREPはBSRHで一致位置を探し、その位置にある部分ビット列をγに置き換えます。ビット列を入れる「語」は、ここでは16ビット分をまとめた単位です。αは2語分なので、ビット位置は0から31まであります。
  1. BSRHから一致位置を受け取ります
    プログラム2では、BSRHを呼び出した後の「LD GR2,GR0」で、検索結果の位置をGR2に移しています。BSRHは、一致位置をGR0に返し、一致しない場合は−1を返します。
    次の「JMI FIN」は、GR2が負の値なら置換処理を行わずに終了する命令です。したがって、この先では一致した場合を考えます。以降、GR2には一致位置が入っています。
  2. 一致位置がどの語にあるかを調べます
    GR3には長さが入っていますが、10行目で16に置き換え、11行目でGR2を引いています。その結果、GR3には「16 − 」が入ります。これは、ビット位置から1語目の末尾までに残っているビット数です。
    この値と長さを比べることで、一致部分の位置を次のように判定しています。
    判定一致部分の場所
    かつ1語目と2語目にまたがる
    かつ1語目だけにある
    2語目だけにある
    2語目だけにある場合は、GR3の値「16 − 」が0以下になります。そのため、12行目と13行目からONL2へ進みます。
  3. cで、2語目の中での位置を計算します
    ONL2に進んだとき、GR2には、GR3には「16 − 」が入っています。30行目の「SUBA GR2,GR3」の後、GR2を「」にしたいとコメントにあります。
    そのためには、GR2をいったん0にしてからGR3を引きます。
    したがって、cには「LD GR2,=0」を入れます。これにより、GR2には2語目の先頭を0としたときの一致位置が入ります。2語目の処理に移る前に、この位置を計算しているということです。
  4. dで、置換するビットをγにします
    プログラムでは、最初に「GR6,=#FFFF」からマスク(処理するビット範囲を選ぶためのビット列)を作っています。GR3をとして右にずらした後、全ビットを反転することで、上位ビットが1のマスクになります。γも左詰めで設定されるため、γのビットとマスクは同じ位置にそろっています。
    S1では、γとマスクを一致位置に合わせてずらします。その後、S2では次の処理を行います。
    • 38行目でマスクを反転します。
    • 39行目のAND(両方のビットが1のときだけ1にする演算)で、置換範囲のビットを0にし、それ以外のビットを残します。
    • 40行目で、置換範囲にγのビットを加えます。
    置換範囲をいったん0にしてからγを加える必要があります。そうすれば、γに0がある位置も、元のビットが残らず正しく0になります。ここでは、どちらかのビットが1なら1にするOR(論理和)を使います。
    したがって、dには「OR GR2,GR4」を入れます。
  5. 2語にまたがる場合も同じ処理を使います
    一致部分が1語目と2語目にまたがる場合、プログラムはまず1語目を処理します。その後、γとマスクを2語目用に調整し、GR1を次の語のアドレスに進めてから2語目を処理します。
    2語目だけにある場合も、cで求めた「」を使ってγとマスクをその語の中の位置に合わせます。どちらの場合も、S2が置換するビット範囲だけをγに置き換える仕組みです。

誤りやすいポイント

  • cでGR2に16を設定すると、「16 − (16 − ) = 」となり、求めたい「」にはなりません。GR2を0にしてからGR3を引くことで、目的の値になります。
  • cの計算に使うGR3はではありません。10行目と11行目の処理後は、「16 − 」です。
  • dをANDにすると、γのビットが0の位置で、置換範囲を0にした値がそのまま残ります。γのビットを反映するにはORが必要です。
  • ORだけでは、γの0の位置に元のビットが残る可能性があります。そのため、先にマスクを反転してANDを行い、置換範囲を0にしています。

FAQ

Q: 2語目の中での位置が「」になるのはなぜですか。
A: 全体のビット位置は、1語目の16ビット分を含んでいます。2語目の先頭を位置0として数えるには、1語目の16ビット分を引きます。
Q: γのビットが0の位置も、正しく置き換えられますか。
A: はい。S2で先に置換範囲の元のビットを0にしてから、γをORします。そのため、γの0もそのまま置換結果に反映されます。
Q: 一致部分が1語目と2語目にまたがるとき、なぜS2を2回呼びますか。
A: 置換対象が2つの語に分かれているためです。1語目に入る部分を処理した後、γとマスクを2語目用に調整して、残りの部分を処理します。

関連キーワード: ビット列、部分ビット列検索、ビットマスク、論理シフト、論理和

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

この設問をAIに質問する

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

 次の設定でプログラム2を実行したとき、行番号23の命令実行直後のGR6に格納されている値として正しい答えを、解答群の中から選べ。    α:1語目 #FFF3    2語目 #7FFF  β:  n:5  γ:    解答群  ア:#0003  イ:#0007  ウ:#8000  エ:#C000  オ:#E000  カ:#F000

模範解答

オ

解説

解答の導き方

問われているのは、プログラム2の行番号23を実行した直後のGR6です。まずBSRHが一致位置を求め、その後にプログラム2がGR6をどのように変えるかを追います。
1. BSRHが見つける位置を確認します。
問題文では、BSRHはαを先頭から調べ、「最初に一致する部分ビット列の先頭のビット位置p」を返します。
αの1語目と2語目は、2進数で次のように表せます。
  • 1語目の#FFF3:1111111111110011
  • 2語目の#7FFF:0111111111111111
βは11011です。αのビット位置14から並ぶ5ビットは、1語目のビット位置14、15と、2語目のビット位置16、17、18を合わせて11011になります。
これより前には一致しません。ビット位置0~11はすべて1なので、βの3ビット目に必要な0がありません。最初の0はビット位置12ですが、そこから候補になる位置を調べても、ビット位置10からは11001、ビット位置11からは10011となり、一致しません。したがって、BSRHが返す位置はです。
2. BSRHから戻った直後の値を整理します。
プログラム1の説明には、BSRHから戻るときにGR1~GR7の内容を元に戻すとあります。したがって、BSRHの呼出し前に設定されたやγの値は、そのままプログラム2で使えます。一方、検索位置はGR0に返されます。
プログラム2の行番号4で、GR0の値をGR2に移すため、GR2は14になります。
3. プログラム2でGR6に作るマスクを確認します。
行番号6~8では、GR6を次のように設定します。
  • 行番号6:GR6は#FFFF
  • 行番号7:GR3はなので、GR6を論理右シフトします。論理右シフトは、右にずらした分の左側を0で埋める処理です。結果は#07FFです。
  • 行番号8:#FFFFとのXOR(同じ位置のビットが異なるときに1にする演算)を行い、結果は#F800です。
つまり、この時点のGR6は#F800です。
続いて、行番号9~11でGR7にを保存し、GR3を「16-p」にします。
行番号14ではGR3の2とGR7の5を比較します。2の方が小さいため、行番号15のJMIによってNEXTへ進みます。
4. 行番号23までのGR6の変化を追います。
NEXTの処理では、行番号17~18でγとマスクをそれぞれ保存します。
γはを左詰めにした値なので、GR4は#F000です。保存時点では、GR5が#F000、GR7が#F800です。
行番号19のCALL S1では、GR4とGR6をビット位置だけ論理右シフトしてから、1語目の処理を行います。その後、行番号20~21で、保存しておいた値をGR4とGR6に戻します。したがって、行番号22~23の直前は次の状態です。
レジスタ行番号22~23の直前
GR32
GR4#F000
GR6#F800
行番号23は、GR6をGR3の値である2ビット分、論理左シフトします。論理左シフトでは、右側に0を補い、左端からあふれたビットは捨てます。
これを2ビット左シフトすると、先頭からあふれたビットを捨てて、
となります。したがって、行番号23の命令実行直後のGR6は#E000です。

誤りやすいポイント

  • BSRHの戻り値はGR0に設定されます。プログラム2の行番号4でGR2に移されるため、以降のGR2は検索位置として使われます。
  • 行番号11のGR3はではなく、の値です。この問題ではです。
  • 行番号19のS1ではGR4とGR6が一度右シフトされますが、行番号20~21で保存した値に戻されます。行番号23の計算には、戻された#F800を使います。
  • 行番号23は右シフトではなく左シフトです。また、16ビットから左にはみ出たビットは残りません。

FAQ

Q: なぜ行番号15からNEXTへ進むのですか?
A: GR3は、GR7はです。行番号14で比較すると2の方が小さいため、JMIの条件が成立します。これは、一致した部分ビット列が1語目と2語目にまたがる場合の処理です。
Q: 行番号20~21で値を戻すのはなぜですか?
A: S1の処理中にGR4とGR6は右シフトされ、1語目の処理に使われます。2語目の処理では、保存しておいた元のγとマスクを使うため、値を戻しています。
Q: 行番号23でGR6が左シフトされるのはなぜですか?
A: 一致位置がビット位置14なので、1語目には先頭の2ビット分が入り、残りが2語目に続きます。行番号23では、マスクを2語目の処理に合う位置へ移すために2ビット左シフトしています。

関連キーワード: ビット列、論理シフト、ビットマスク、XOR、条件分岐

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

この設問をAIに質問する

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

戦国ITクイズ機能

\ せっかくなら /

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

クイズ画面へ遷移する→

すぐに利用可能!

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

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