close

令和元年度 秋期 基本情報技術者試験 午後 問12 詳細解説


基本情報技術者試験(FE)過去問題

パック10進数とは4ビットで10進数の1桁を表す方式です。符号は最後(一番右側)の4ビットで表します。

加算する場合は絶対値表示のように符号部分を外して計算、4ビットで1桁(0から9まで)なので繰り上がり(1001+1は1010ではなく0000と上位の桁の数+1)繰り下がり(0000-1は1111ではなく1001と上位の桁の数-1)の際に注意が必要です。実際この点の確認不足で問いが一つ無くなっています。

問1

問1は符号が同一の二つの数値を足すプログラムです。

ADDP1

START
プログラムの先頭を定義

RPUSH
GR の内容をスタックに格納

ST GR1,A
GR1に格納されているデータをアドレスAに格納する。

ST GR2,B
GR2に格納されているデータをアドレスBに格納する。

LAD GR3,4
4(100)をGR3に格納する。;ビット数カウンタの初期化

[a]

ST GR1,RESULT
GR1に格納されているデータをアドレスRESULTに格納する。;符号部を退避

[a]の直後に「符号部を退避」とコメントがかかれています。ということはaの処理をしてGR1が符号部分だけになっていることがわかります。

符号部分は最後の4ビットなのでそこを取り出すためにはGR1と000Fの論理積をとればよいことがわかります。aの答えは「AND GR1,=#000F」です。RESULTには符号部分だけ格納されています。

LD GR1,A
実効アドレスAに格納されているデータをGR1に格納する。FRのOFが0になる。

SRL GR1,0,GR3
符号を含みGR1をGR3で指定し たビット数だけ右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

LD GR2,B
実効アドレスBに格納されているデータをGR2に格納する。FRのOFが0になる。

SRL GR2,0,GR3
符号を含みGR2をGR3で指定し たビット数だけ右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

この処理で二つのレジスタに格納されているデータは数値部だけになっています。

LOOP

AND GR1,=#000F
GR1と16進数000Fとの論理積をGR1に格納する。OF には 0 が設定される。

AND GR2,=#000F
GR2と16進数000Fとの論理積をGR2に格納する。OF には 0 が設定される。

一桁分だけ取り出します。

LAD GR0,0
実効アドレス0をGR0に格納する。

GR0の値を初期化します。

ADDL GR1,GR2
GR1とGR2を符号なしの数として足した値をGR1に格納する。

CPL GR1,=10
GR1と10進数10を符号なしの値として比較を行いその結果によってFRの値が変わる。OF には 0 が設定される。;10以上の場合は桁上げ

[b]

SUBL GR1,=10
GR1と10進数10を符号なしの数として引いたものをGR1に格納する。

LAD GR0,1
実効アドレス1をGR0に格納する。

二つの数を足した結果10以上になって桁上げが生じた場合に、GR0を1(キャリー分)にし、足した値から10を引きます。bではその分岐をする処理が書かれているはずです。bの直後が桁上げが生じた場合の処理なので、bでは桁上げが生じていない場合の分岐を記述しジャンプする場所は二つの処理後のMARGEになります。桁上げが生じない場合は「CPL GR1,=10」でGR1より10が大きいのでFRの値はSF=1になります。SF=1で分岐するのはJMIなので、bの答えは「JMI MARGE」になります。

MARGE

[c]

OR GR1,RESULT
GR1とRESULTに格納されている値の論理和をGR1に格納する。OF には 0 が設定される。;中間結果との統合。

GR1の最後の4ビットには足した一桁の数が入っています。RESULTには最初は符号桁、そのあと中間結果が格納されていきます。そのままGR1とRESULTを足すと不必要な足し算になるので、桁を合わせて足すために足す前に右シフトした分だけ左シフトしてから足す必要があります。そのためcには左シフトの命令が入ります。シフトするビット数はGR3に格納されています。cの答えは「SLL GR1,0,GR3」になります。

LAD GR3,4,GR3
4とGR3を足した値をGR3に格納する。

CPL GR3,=16
GR3と10進数10を符号なしの値として比較を行いその結果によってFRの値が変わる。OF には 0 が設定される。

JZE FIN
ZF=0の時、 FINに分岐す る。分岐しないときは,次の命令に進む。;終了判定

足し算するデータは数値部が3桁なので、ビットシフトするのは4ビット、8ビット、12ビットの三回です。2回目以降のビットシフトは4足した後に行うので、ビットシフトの桁数を保持しているGR3が12より大きい場合、つまり16の場合は処理が終わっていることになるのでFINにジャンプして終了します。

ST GR1,RESULT
GR1に格納されているデータをRESULTに格納する。;中間結果を退避

LD GR1,A
実効アドレスAに格納されているデータをGR1に格納する。FRのOFが0になる。

SRL GR1,0,GR3
符号を含みGR1をGR3で指定し たビット数だけ左右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

LD GR2,B
実効アドレスBに格納されているデータをGR2に格納する。FRのOFが0になる。

SRL GR2,0,GR3
符号を含みGR2をGR3で指定し たビット数だけ左右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

ADDL GR1,GR0
GR1とGR0を符号なしの数として足した値をGR1に格納する。

一回目と同様にデータの読み込みとビットシフトをしています。違うところは下の桁からの桁上がりがあるところです。桁上がりがあればGR0=1、なければGR=0なので、それをGR1に足すことで下の桁の計算結果が反映されます。

JUMP LOOP
無条件にLOOPに分岐する。

FIN

LD GR0,GR1
GR1に格納されているデータをGR0に格納する。FRのOFが0になる。

RPOP
スタックの内容を GR に格納

RET
SPの内容が指し示すアドレスに入っている値をPRに格納し、SPの値を符号なしの値として+1してSPに格納する。

A

DS 1

B

DS 1

RESULT

DS 1

END

問2

符号が異なる場合のプログラムです。二つの値の足し算をしているのですが、符号が違うので実際は引き算になります。絶対値の引き算をして、符号は絶対値の大きいほうの値のものになります。例:9+(−4)=5、−9+4=−5

ADDP2

START
プログラムの先頭を定義

RPUSH
GR の内容をスタックに格納

CPL GR1,GR2
GR1とGR2を符号なしの値として比較を行いその結果によってFRの値が変わる。OF には 0 が設定される。

[d]

LD GR4,GR1
GR1に格納されているデータをGR4に格納する。FRのOFが0になる。

LD GR1,GR2
GR2に格納されているデータをGR1に格納する。FRのOFが0になる。

LD GR2,GR4
GR4に格納されているデータをGR2に格納する。FRのOFが0になる。

CPL命令でGR1とGR2を比較し、そのあとGR1とGR2を入れ替えるか否かの処理をしています。引き算をする命令が「SUBL GR1,GR2」しかないので、絶対値の引き算をするためにはGR1のほうが大きな数字だということがわかります。dの命令の後にGR1とGR2を入れ替えている処理があります。この一連の処理はGR2のほうがGR1よりも大きい時に行います。なので正分岐でこの処理をジャンプすればいいのでdの答えは「JPL INI」になります。

INI

ST GR1,A
GR1に格納されているデータをアドレスAに格納する。

ST GR2,B
GR2に格納されているデータをアドレスBに格納する。

LAD GR3,4
実効アドレス4をGR3に格納する。ビット数カウンタの初期化

[a]AND GR1,=#000F
GR1と16進数000Fとの論理積をとりその値をGR1に格納する。

ST GR1,RESULT
GR1に格納されているデータをアドレスRESULTに格納する。;符号部を退避

LD GR1,A
実効アドレスAに格納されているデータをGR1に格納する。FRのOFが0になる。

SRL GR1,0,GR3
符号を含みGR1をGR3で指定し たビット数だけ左右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

LD GR2,B
実効アドレスBに格納されているデータをGR2に格納する。FRのOFが0になる。

SRL GR2,0,GR3
符号を含みGR2をGR3で指定し たビット数だけ左右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

LOOP

AND GR1,=#000F
GR1と16進数000Fとの論理積をGR1に格納する。OF には 0 が設定される。

AND GR2,=#000F
GR2と16進数000Fとの論理積をGR2に格納する。OF には 0 が設定される。

LAD GR0,0
実効アドレス0をGR0に格納する。

SUBL GR1,GR2
GR1とGR2を符号なしの数として引いた値をGR1に格納する。

JPL MARGE
SF=0,ZF=0の時MARGEに分岐。

[e]

ADDL GR1,=10
GR1と10進数10を符号なしの数として足したものをGR1に格納する。

LAD GR0,1
実効アドレス1をGR0に格納する。

GR1-GR2の結果、正の場合にMARGEにジャンプしています。なのでeの後の処理は、10を足してGR0=1(桁借り分)しているので負の時になります。ですがこのままJPLの分岐だけでは0の場合も負と同じ処理をして計算結果が違ってきます。なので0の場合も分岐させる必要があります。eの答えは「JZE MERGE」になります。

MARGE

[c]SLL GR1,0,GR3

OR GR1,RESULT
GR1とRESULTに格納されている値の論理和をGR1に格納する。OF には 0 が設定される。

LAD GR3,4,GR3
アドレス4とGR3を足した実効アドレスをGR3に格納する。

CPL GR3,=16
GR3と10進数10を符号なしの値として比較を行いその結果によってFRの値が変わる。OF には 0 が設定される。

JZE FIN
ZF=0の時、 FINに分岐す る。分岐しないときは,次の命令に進む。;終了判定

ST GR1,RESULT
GR1に格納されているデータをRESULTに格納する。;中間結果を退避

LD GR1,A
実効アドレスAに格納されているデータをGR1に格納する。FRのOFが0になる。

SRL GR1,0,GR3
符号を含みGR1をGR3で指定し たビット数だけ左右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

LD GR2,B
実効アドレスBに格納されているデータをGR2に格納する。FRのOFが0になる。

SRL GR2,0,GR3
符号を含みGR2をGR3で指定し たビット数だけ左右にシフトする。 シフトの結果,空いたビット位置には 0 が入る。OF にはレジスタから最後に送り出 されたビットの値が設定される。

[f]

問1を参考にすればfには桁借り分(GR0)を引けばいいことがわかります。なので「SUBL GR1,GR0」とすればよさそうです。ですがこの計算結果で桁借り、つまりGR0の最後の4ビットが0000の場合は-1すると1111になります。パック10進数は0000から1001までしかとらないので計算を工夫する必要があります。

GR0=1場合のみ処理を行い、0000以外ならGR1-GRO(=GR1-1)、0000の場合はGR1-16+10-GR0=GR1-8-GR0とすればいいでしょう。

なのでfは「CPL GR0,0 JZE LOOP AND GR1,=#000F JPL FBUNKI SUBL GR1,=#0008 FBUNKI SUBL GR1,GRO」と書けるでしょう。いろいろ記述方法があると思うので考えてみてください。

JUMP LOOP
無条件にLOOPに分岐する。

FIN

LD GR0,GR1
GR1に格納されているデータをGR0に格納する。FRのOFが0になる。

CPL GR0,=#000D
GR0と16進数で000Dを符号なしの値として比較を行いその結果によってFRの値が変わる。OF には 0 が設定される。

JNZ FIN2

LAD GR0,#000C
16進数で000CをGR0に格納する。

FIN2

RPOP
スタックの内容を GR に格納

RET
SPの内容が指し示すアドレスに入っている値をPRに格納し、SPの値を符号なしの値として+1してSPに格納する。

A

DS 1

B

DS 1

RESULT

DS 1

END

問3

符号の組み合わせで二つのプログラムに振り分けます。同符号の場合へADDP1、異符号の場合はADDP2。符号部分は正が1100、負が1101で最終桁だけ違います。そこを利用すればうまく振り分けられるはずです。

LD GR0,GR1

[g]

SRL GRO,1

[h]

CALL ADDP1

JUMP FIN

P2

CALL ADDP2

FIN

RET

END

SRLの右シフトで最後に送り出されたビットの値がOFに設定されます。OFで分岐する命令はJOVだけなのでhにはJOVが入ります。OF=1の時の分岐しか命令がないので分岐先のP2(異符号の場合)にGR1とGR2演算結果の最終ビットが1である必要があります。1100と1100、1101と1101の演算で最終ビットが0、1100と1101の演算で最終ビットが1になるのは、XORです。なのでgの答えは「XOR GR0,GR2」、hの答えは「JOV P2」になります。

科学の部屋[工学・化学]