平成29年春期試験午後問題 問12
問12 ソフトウェア開発(アセンブラ)
次のアセンブラプログラムの説明及びプログラムを読んで,設問1~3に答えよ。
〔プログラム1の説明〕
64ビット符号なし整数の加算を行う副プログラム ADD64 である。64ビット符号なし整数の主記憶への格納方法を,図1に示す。
〔プログラム1の説明〕
64ビット符号なし整数の加算を行う副プログラム ADD64 である。64ビット符号なし整数の主記憶への格納方法を,図1に示す。
- GR1 及び GR2 には,それぞれ次の内容が設定されて,主プログラムから渡される。
- GR1,GR2
- 加算の対象となる二つの64ビット符号なし整数を格納する領域の先頭アドレス。各領域はそれぞれ連続した4語から成る。
- 副プログラム ADD64 は,GR1 に設定されたアドレスから始まる連続した4語の領域に,加算の結果を格納する。このとき,桁あふれは発生しないものとする。
- 副プログラム ADD64 から戻るとき,汎用レジスタ GR1~GR7 の内容は元に戻す。
広告
設問1
プログラム1中の に入れる正しい答えを,解答群の中から選べ。
a,b に関する解答群
- AND GR5,=1
- CPL GR3,=0
- CPL GR3,GR1
- CPL GR3,GR2
- LD GR5,=1
c に関する解答群
- JOV LOOP
- JUMP LOOP
- JZE LOOP
解答選択欄
- a:
- b:
- c:
- a=オ
- b=ウ
- c=イ
解説
まず〔プログラム1〕の先頭からaに至るまでトレースしていきます。- 3行目
- GR1 と GR2 で相対位置が同じ番地同士の加算結果を格納する GR0 を0で初期化する
- 4~5行目
- GR3 と GR4 に各被演算数の最下位16ビットの番地(図1中のN+3番地)のアドレスを格納する
- 6行目
- 下位ビット列からの繰り上がり(後述)を保持する GR5 を0で初期化する
- 7行目
- GR0 に一方の被演算数の16ビット(GR3が示すアドレスのメモリ内容)を加算する
- 8行目
- GR0 にあふれが生じたら、ラベルOV1に分岐する
〔aについて〕
選択肢はLD命令とCPL命令に分かれますが、[a]の次行の命令は分岐命令ではないので、ここでCPL命令によりフラグレジスタを設定しても何ら意味がありません。よって、LD命令のどちらかが入ります。
2か所の[a]は、どちらもJOV命令での分岐後に行われているので GR0 にあふれが生じたときに行う処理です。あふれが生じるということは、加算の結果16ビットで表現できる数値を超えてしまったということであり、桁上がりの処理をしなければなりません。※GR0 への加算処理は7行目と11行目の2か所あり、1つ目が GR1 の値を加算する処理、2つ目が GR2 の値を加算する処理です。あふれが頻繁に生じるのは2つ目の加算処理の方です。
GR5 はループの先頭で0に初期化されており、他に値を設定している箇所もないので「ア」のように 0 AND 1 を行っても永久に0のままです。よって、ここでは筆算の繰り上がりのように上位桁への桁上がりの1を GR5 に格納しておく「オ」の命令が適切です。GR5 に設定された1は、その後16行目で GR0 にロードされることで、次の上位16ビットの加算に反映されます。
∴a=オ:LD GR5,=1
〔bについて〕
[a]はLD命令だったので、[b]にはCPL命令のいずれかが入ります。
[b]の次行では、CPL命令で2つのオペランドが一致した(ZF=1)ときにはJZE命令でラベルEXITに分岐させているので、ここではプログラムの終了判定を行っていることがわかります。19~20行目のSUBL命令で GR3 と GR4 のアドレスを1つ前に移動させていることからわかるように、このプログラムでは、N+3番地同士の加算→N+2番地同士の加算→N+1番地同士の加算→N番地同士の加算、というように最下位16ビットから最上位16ビットの順番で計算を行っています。このとき、GR3 から1引くことを3回繰り返すと GR1 のアドレスと同一になります。GR3 が GR1 に達したということは最上位16ビットの加算まで終了したということですので、プログラムを終了することになります。よって、CPL命令で GR3 と GR1 に格納されたアドレスを照合する処理が入ります(手続き上は「CPL GR4,GR2」でもOKです)。∴b=ウ:CPL GR3,GR1
〔cについて〕
直前のSUBL命令の結果である GR4 の値によってループの先頭に戻る分岐命令が入ります。GR4 は GR2+α のアドレスを保持しており、アドレス値に対して-1を行っても0やオーバーフローになることはありません。よって、JUMP命令で無条件にループ先頭に戻す「イ」が適切です。
∴c=イ:JUMP LOOP
広告
設問2
次の記述中の に入れる正しい答えを,解答群の中から選べ。
GR1 及び GR2 に設定したアドレスから始まる連続した4語の領域に,図2のとおりに値を格納して副プログラム ADD64 を実行したとき,行番号7の命令を2回目に実行した後の GR0 の値はdである。
GR1 及び GR2 に設定したアドレスから始まる連続した4語の領域に,図2のとおりに値を格納して副プログラム ADD64 を実行したとき,行番号7の命令を2回目に実行した後の GR0 の値はdである。
d に関する解答群
- #0000
- #0001
- #2E0C
- #2E0D
- #3F1D
- #3F1E
解答選択欄
- d:
- d=エ
解説
〔dについて〕1回目のループの7行目で、GR0 に(GR1)+3番地の値が加算されます。さらに、11行目で(GR2)+3番地の値が加算されます。#AB84 と #B759 を加算するとあふれが生じるので[a]の処理により、GR5 に桁上がりの1が設定されます。その後、16行目で GR0 に GR5 の1がロードされ、19行目の GR3 から1引く処理で GR3 が(GR1)+2番地を指すようになります。その後ループ先頭に戻り、2回目の7行目では、GR0(=1) に GR3 が指す(GR1)+2番地の #2E0C が加算されます。よって、7行目の命令2回目に実行した後の GR0 の値は、#2E0C に1を加算した #2E0D になっています。
∴d=エ:#2E0D
広告
設問3
副プログラム ADD64 を使用して,32ビット符号なし整数の乗算を行う副プログラム MUL32 を作成した。プログラム2中の に入れる正しい答えを,解答群の中から選ベ。
〔プログラム2の説明〕
〔プログラム2の説明〕
- 32ビット符号なし整数の主記憶への格納方法を,図3に示す。
- GR1~GR3 には,それぞれ次の内容が設定されて,主プログラムから渡される。
- GR1,GR2:
- 乗算の対象となる二つの32ビット符号なし整数を格納する領域の先頭アドレス。各領域はそれぞれ連続した2語から成る。
- GR3:
- 乗算結果となる64ビット符号なし整数を格納する領域の先頭アドレス。領域は連続した4語から成る。
- 副プログラムMUL32から戻るとき,汎用レジスタ GR1~GR7 の内容は元に戻す。
e,f に関する解答群
- JMI LOWORD
- JNZ LOWORD
- JPL LOWORD
- JZE LOWORD
- LAD GR2,TEMP
- LD GR2,=1
- LD GR2,GR3
- LD GR1,TEMP
解答選択欄
- e:
- f:
- e=ア
- f=オ
解説
〔プログラム2〕の開始からラベルLOOPの直前までの処理で、GR7(=TEMP)と GR3 から始まるメモリ領域の内容は次のようになっています。〔eについて〕消去法的になりますが、〔プログラム2〕にはラベルLOWORDが定義されているにもかかわらず、このラベルに分岐させる命令がないので、[e]にはラベルLOWORDに分岐させる命令が入るとわかります。
ループの冒頭では、ループカウンタである GR5 の値を GR6 に格納した後に、GR6 から16を引いています。つまり、SUBL命令直後の GR6 は、ループカウンタが16未満のときには負の数、16以上のときは0又は正の数です。この GR6 の値により分岐するわけですが、ラベルLOWORDに分岐する場合としない場合では次のように処理が変わります。
- ラベルLOWORDに分岐する場合
- GR2(=32ビットの乗数)の下位16ビットを GR0 にロードし、GR5 の値だけ右論理シフトする。
- ラベルLOWORDに分岐しない場合
- GR2 の上位16ビットを GR0 にロードし、GR6 の値だけ右論理シフトする。
この分岐は、ループカウンタが15以下であれば乗数の下位16ビットを、16以上であれば上位16ビットを操作対象とする分岐処理になっています。
∴e=ア:JMI LOWORD
※GR6 の値が正の数として評価され、非常に大きなビット数をシフトさせることになってしまいます。
〔fについて〕
この処理の直後に副プログラム ADD64 が呼ばれています。副プログラム ADD64 は、GR1,GR2に加算対象となる64ビット符号なし整数を格納する領域の先頭アドレスを格納して呼び出されます。「オ」から「ク」の選択肢のうち、先頭アドレスを GR2 に格納するのは「オ」だけなので、これが正解となります。
ここではループの度にTEMPの値を2倍する処理が行われています。
「カ」は GR2 に1番地が設定されるので誤り、「キ」は乗算結果の先頭16ビットの値が設定されるので誤り、「カ」はTEMPの先頭16ビットの値が設定されるので誤りです。
∴f=オ:LAD GR2,TEMP
〔プログラム2〕では以下の流れで乗算を行っています。
- 乗数32ビットを最下位から順に1ビットずつ確認する
- ビットが1なら乗算結果にTEMPの値を加算する
- TEMPを2倍する
- ループカウンタが31なら終了、そうでなければ1.に戻る
広告
広告