基本情報技術者試験 アセンブラ(CASL) 簡単に5割
平成21年春期,平成21年秋期
平成21春期
概要
解き方
設問1-a
穴埋め箇所
07 LP SRL GR2,1 ; 乗数を1ビット右にシフト
08 [ a ] ;
09 JZE FIN ;
10 JUMP NEXT ; 加算処理をスキップ
選択肢
- JMI ADD32
- JMI LP
- JOV ADD32
- JOV LP
- JPL ADD32
- JPL LP
解法
アセンブラにおける乗算は、以下のように計算されます。
- 乗数のビットが1の部分を検索する。
- 上記で検出されたビット位置に応じて被乗数をシフトする。
- 上記で得られた被乗数を合計する。
乗数のビットが1の部分を検索する方法としては、以下のような方法があります。
<右シフトの場合>
- 右シフトして、オーバーフロー発生有無で判定する。 [平成21年春期]
- #0001でANDして結果が0か1かで判定する。判定後に右にシフトする。 [平成29年春期]
<左シフトの場合>
- サインフラグがONかOFFで判定する。判定後に左論理シフトする。 [平成27年春期]
- 左論理シフトして、オーバーフロー発生有無で判定する。
本プログラムでは、右シフト後に判定を行っているので、「JOV」に絞り込まれます。
ここで「JOV LP」を選択すると「ADD32」の加算処理が全く実行されなくなるので、 「JOV ADD32」が正解となります。
例:1010(被乗数) × 0101(乗数)
乗数を1ビット右にシフト後、オーバーフロー有無を確認し、被乗数を加算する。
■
|乗数を1ビット右にシフト
|▲オーバーフロー発生? /*シフト前の最下位ビットがONか?*/
||加算処理実施 /*計算結果 ← 計算結果 + 被乗数*/
|▼
|▲シフト後ゼロ? /*乗算終了?*/
||計算処理終了
|▼
|被乗数を1ビット左にシフト
■
⇒ オーバーフロー時に加算処理に分岐する、「ウ:JOV ADD32」が正解となります。
別解
選択肢について
選択肢は、分岐先として“LP”,“ADD32”の二種類、分岐命令として"“,”“,”"の三種類あります。
分岐先の絞り込み
プログラムの中から、分岐元のない分岐先がないかを検索します。検索の結果、“ADD32”への分岐元がないので、 “ADD32”に分岐する三つの選択肢に絞り込むことができます。
(他の穴埋め箇所の選択肢にも“ADD32”に分岐する命令はない。)
- ア. JMI ADD32
- ウ. JOV ADD32
- オ. JPL ADD32
行番号07の「SRL GR2,1」は最上位ビット(符号)に“0”が設定され、フラグレジスタのSFフラグは“0”になります。
- [ a ]に“JMI”を適用した場合:
→必ず分岐せず“JMI”が無意味な処理になります。
- [ a ]に“JPL”を適用した場合:
→必ず“JPL”/“JZE”で分岐し、“JUMP”が無意味な処理になります。
⇒ 「ウ:JOV ADD32」が残ります。
←
設問1-b
穴埋め箇所
11 ADD32 ADDL GR6,GR4 ; 32ビット+32ビット→32ビット
12 ADDL GR7,GR5 ;
13 [ b ] ;
14 JUMP NEXT ;
15 ADJ1 ADDL GR6,=1 ; けた上げ処理
16 NEXT
選択肢
- JMI ADJ1
- JMI ADJ2
- JOV ADJ1
- JOV ADJ2
- JPL ADJ1
- JPL ADJ2
解法
アセンブラにおける32bitデータの加算は、一般的に、以下のように実施されます。
下位16ビットを加算後、オーバーフロー有無を確認し、桁上げ処理を行う。
|上位16ビットを加算
|下位16ビットを加算
|▲オーバーフロー発生? /*桁上がり発生?*/
||上位16ビットに1加算 /*桁上がり処理*/
|▼
⇒ オーバーフロー発生時に桁上がり処理に分岐する、「ウ:JOV ADJ1」が正解となります。
別解
出題されたプログラムには、ADJ1に分岐する命令が記述されていませんので、ADJ1に分岐する三つの選択肢に絞り込むことができます。
- ア. JMI ADJ1
- ウ. JOV ADJ1
- オ. JPL ADJ1
- “JPL ADJ1”を適用した場合
→行番号12の加算結果が0x0001~0x7fffの時に分岐し、上位語(GR4)に1加算します。
- “JMI ADJ1”を適用した場合
→行番号12の加算結果が0x8000~0xffffの時に分岐し、上位語(GR4)に1加算します。
- “JOV ADJ1”を適用した場合
→行番号12の加算結果が0xffffを超えた時に分岐し、上位語(GR4)に1加算します。
←
設問1-c
穴埋め箇所
05 LD GR4,0,GR1 ; 被乗数 上位語の取出し
06 LD GR5,1,GR1 ; 被乗数 下位語の取出し
(略)
16 NEXT SLL GR4,1 ; 被乗数(32ビット)を1ビット左にシフト
17 [ c ] ;
18 JOV ADJ2 ;
19 JUMP LP ;
選択肢
- JNZ LP
- JPL LP
- JZE LP
- SLL GR5,1
- SRA GR5,1
- SRL GR5,1
解法
コメントに「被乗数(32ビット)を1ビット左にシフト」と記載されています。
⇒ 被乗数(下位16ビット)を1ビット左にシフトする「エ:SLL GR5,1」が正解となります。
補足
32ビットを左シフトする手順
1. 上位16ビットを左シフト
2. 下位16ビットを左シフト
3. OFフラグがONなら上位16ビットの最下位ビットに“1”を設定
本問では、GR4に上位16ビット、GR5に下位16ビットが格納されています。
「OR GR4,=1」で、最下位ビットに“1”を設定しています。
設問2-d
穴埋め箇所
03 PUSH 0,GR3 ;
04 PUSH 0,GR2 ;
05 LD GR2,1,GR2 ; 乗数下位語を取り出してGR2に設定
06 CALL MULS ; 被乗数×乗数下位語→積(A)
07 POP GR2 ;
08 [ d ] ;
09 LAD GR3,SV ; 結果の格納先として作業領域を設定
10 CALL MULS ; 被乗数×乗数上位語→積(B)
11 [ e ] ;
12 POP GR3 ;
13 ADDL GR6,0,GR3 ; 積(A)の上位語と積(B)の下位語を加算
14 ST GR6,0,GR3 ;
選択肢
- LD GR1,0,GR1
- LD GR1,0,GR2
- LD GR1,1,GR1
- LD GR2,0,GR1
- LD GR2,0,GR2
- LD GR2,1,GR1
解法
副プログラム(MULS)のインプットは以下のとおり。(本文の説明より)- GR1 : 被乗数格納域アドレス
- GR2 : 乗数
- GR3 : 積(計算結果)格納域アドレス
- GR1 : 被乗数格納域アドレス
- GR2 : 乗数(行番号05にて乗数の下位語格納)
- GR3 : 積(計算結果)格納域アドレス
(但し、[ d ]未実施)
- GR1 : 被乗数格納域アドレス
- GR2 : 乗数格納域アドレス
(04行目の「PUSH 0,GR2」で退避した値が、07行目の「POP GR2」で復元されている)
- GR3 : 作業領域(SV)のアドレス
⇒ 副プログラム(MULS)呼出し時、GR2には乗数が格納されている必要があるので、乗数上位語をGR2に設定する「オ:GR2,0,GR2」が正解となります。
補足
1回目のMULSでは「被乗数×乗数下位語→積(A)」(積はMUL呼出時にGR3に設定された積格納域に格納される)
2回目のMULSでは「被乗数×乗数上位語→積(B)」(積は作業域(SV)域に格納される)
が行われます。
設問2-e
穴埋め箇所
03 PUSH 0,GR3 ;
04 PUSH 0,GR2 ;
05 LD GR2,1,GR2 ; 乗数下位語を取り出してGR2に設定
06 CALL MULS ; 被乗数×乗数下位語→積(A)
07 POP GR2 ;
08 [ LD GR2,0,GR2 ] ;
09 LAD GR3,SV ; 結果の格納先として作業領域を設定
10 CALL MULS ; 被乗数×乗数上位語→積(B)
11 [ e ] ;
12 POP GR3 ;
13 ADDL GR6,0,GR3 ; 積(A)の上位語と積(B)の下位語を加算
14 ST GR6,0,GR3 ;
選択肢
- LD GR6,0,GR1
- LD GR6,0,GR2
- LD GR6,0,GR3
- LD GR6,1,GR1
- LD GR6,1,GR2
- LD GR6,1,GR3
解法
行番号13「ADDL GR6,0,GR3」のコメントには、
「積(A)の上位語と積(B)の下位語を加算」
と記載されています。
「0,GR3」が「積(A)の上位語」ですので、GR6には「積(B)の下位語」が格納されている必要があります。
⇒ 積(B)の下位語を取り出すことができる「カ:LD GR6,1,GR3」が正解となります。
補足
行番号11「LD GR6,1,GR3」実施前のレジスタの状態
- GR1 : 被乗数格納域アドレス
- GR2 : 乗数(上位語)
- GR3 : 積(B)格納域アドレス
(「LAD GR3,SV」によってSV域のアドレスが格納されている)
- GR6 : 不定
行番号13「ADDL GR6,0,GR3」実施前のレジスタの状態
- GR1 : 被乗数格納域アドレス
- GR2 : 乗数(上位語)
- GR3 : 積(A)格納域アドレス
(「POP GR3」で積(A)格納域アドレスが復元されている)
- GR6 : 積(B)の下位語
(「LD GR6,1,GR3」で格納される)
補足
コメントにもあるように、積(A)の上位語と積(B)の下位語を加算します。
加算例を10進数の2桁同士の乗算(03×18)を例に記載します。
積(A) 03×08=24 → 積格納域に設定
積(b) 03×01=03 → SV格納域に設定
積(A)の上位語と積(B)の下位語を加算 2(積(A)上位) + 3(積(b)下位) = 5
以上より、03×18 = 54
振り返り
出題趣旨
基本的な演算処理がコンピュータ内部でどのように行われているかを理解しておくことは重要である。 本問は、1語16ビットを操作の基本単位とする命令を基に、まず32ビット×16ビットの乗算を、更にそれを利用して32ビット同士の乗算を実行するプログラムの完成を主題としている。 本問では、シフトを用いた乗算アルゴリズムと必要なけた上げ処理の理解を問うとともに、既存プログラムを用いて、より広い適用範囲をもつプログラムを作成する能力を評価する。
採点講評
問12では、32ビットの乗算を行うプログラムについて出題した。 設問1は、シフトを用いた1語16ビット同士の基本的な乗算を拡張し、被乗数が32ビットという設定で出題した。 正答率は平均的で、おおむね理解されていた。 aではオと誤って解答した受験者が多かった。 論理右シフト命令実行時の各フラグに設定される値が理解できていれば正答できた。 特に右シフト時のOFの設定値に対する理解が不足しているように思われる。 設問2は、設問1の乗算プログラムを組み合わせた応用問題であった。 正答率は低く、あまり理解されていなかった。 いずれも、コメントを参考にして処理の流れを把握し、使用する副プログラム(MULS)のレジスタに設定する値の意味を考えれば、正答できた。
プログラム詳解
〔プログラム1〕
概要
32ビット×16ビットの乗算を行う副プログラム
入力
- GR1 : 被乗数格納域アドレス
- GR2 : 乗数
- GR3 : 積(計算結果)格納域アドレス
○開始
・積を格納するレジスタ初期化(0設定)
・被乗数の取出し
■乗数 ≠ 0
|・乗数を右シフト
|▲シフトでオーバーフロー?
||・積 ← 積 + 被乗数
||▲加算でオーバーフロー?
|||・桁上げ
||▼
|▼
|・被乗数を左シフト
■
・積(計算結果)格納域に計算結果格納
○終了
プログラム
01 MULS START ; 32ビット×16ビット→32ビット
02 RPUSH ;
03 LAD GR6,0 ; 積 上位語の初期化
04 LAD GR7,0 ; 積 下位語の初期化
05 LD GR4,0,GR1 ; 被乗数 上位語の取出し
06 LD GR5,1,GR1 ; 被乗数 下位語の取出し
07 LP SRL GR2,1 ; 乗数を1ビット右にシフト
08 JOV ADD32 ;
09 JZE FIN ;
10 JUMP NEXT ; 加算処理をスキップ
11 ADD32 ADDL GR6,GR4 ; 32ビット+32ビット→32ビット
12 ADDL GR7,GR5 ;
13 JOV ADJ1 ;
14 JUMP NEXT ;
15 ADJ1 ADDL GR6,=1 ; けた上げ処理
16 NEXT SLL GR4,1 ; 被乗数(32ビット)を1ビット左にシフト
17 SLL GR5,1 ;
18 JOV ADJ2 ;
19 JUMP LP ;
20 ADJ2 OR GR4,=1 ;
21 JUMP LP ;
22 FIN ST GR6,0,GR3 ; 乗算結果の格納
23 ST GR7,1,GR3 ;
24 RPOP ;
25 RET ;
26 END ;
〔プログラム2〕
概要
32ビット×32ビットの乗算を行う副プログラム
入力
- GR1 : 被乗数格納域アドレス
- GR2 : 乗数格納域アドレス
- GR3 : 積(計算結果)格納域アドレス
○開始
・積(計算結果)格納域アドレス 退避
・乗数格納域アドレス 退避
・被乗数×乗数下位(積(a)がMUL呼出元が用意した領域に格納)
・乗数格納域アドレス 復元
・計算結果格納アドレスをSV域に変更
・被乗数×乗数上位(積(b)がSV域に格納)
・積(b)の下位を取出し、積(a)の上位に加算
○終了
注意点
積(b)の上位は無視されます。
入力可能なデータは、積(b)の上位に値が設定されない数値です。
プログラム
01 MUL START ; 32ビット×32ビット→32ビット
02 RPUSH ;
03 PUSH 0,GR3 ;
04 PUSH 0,GR2 ;
05 LD GR2,1,GR2 ; 乗数下位語を取り出してGR2に設定
06 CALL MULS ; 被乗数×乗数下位語→積(A)
07 POP GR2 ;
08 LD GR2,0,GR2 ;
09 LAD GR3,SV ; 結果の格納先として作業領域を設定
10 CALL MULS ; 被乗数×乗数上位語→積(B)
11 LD GR6,1,GR3 ;
12 POP GR3 ;
13 ADDL GR6,0,GR3 ; 積(A)の上位語と積(B)の下位語を加算
14 ST GR6,0,GR3 ;
15 RPOP ;
16 RET ;
17 SV DS 2 ;
18 END ;
平成21秋期
概要
解き方
設問1-a、b
穴埋め箇所
行番号8のSUBAの実行直後における GR2 の値は,[ a ]であり,GR4 の値は[ b ]である。
行番号17のSLLの実行直後における GR0 の内容は,[ c ]であり,GR5 の内容は[ d ]である。
トレース対象箇所
03 LD GR4,GR2 ; GR4 ← p
04 SRL GR4,4 ; GR4 ← p/16
05 ADDA GR1,GR4 ; GR1 を置換え対象語(第 i 語)に位置付ける。
06 AND GR2,=#000F ;
07 LD GR4,=16 ;
08 SUBA GR4,GR2 ; 実行後のGR2,GR4値は?
選択肢
- 1
- 5
- 7
- 9
- 11
- 13
解法
出題された条件を図1に記入します。
更に、分かる範囲で補足の情報を図1に追記します(赤字の数字)。
出題された条件をソースに適用しトレースします。
03 LD GR4,GR2 ; GR4 ← p(=55)
04 SRL GR4,4 ; GR4 ← p/16(=55/16=3)
05 ADDA GR1,GR4 ; GR1 ← GR1 + 3
; (第4語のアドレス取得)
06 AND GR2,=#000F ; GR2 ← p mod 16(=55 mod 16=7)
; (第4語のビット列挿入ビット位置取得)
07 LD GR4,=16 ;
08 SUBA GR4,GR2 ; GR4 ← 16 - 7 = 9
; (第4語に挿入されるビット長取得)
⇒ トレースの結果、GR2 = 7, GR4 = 9 で、「ウ」「エ」が正解となります。
設問1-c、d
トレース対象箇所
09 LD GR5,GR0 ;
10 LD GR6,=#8000 ;
11 SUBA GR3,=1 ;
12 SRA GR6,0,GR3 ;
13 LD GR7,GR6 ;
14 SRL GR0,0,GR2 ;
15 SRL GR6,0,GR2 ;
16 SLL GR5,0,GR4 ;
17 SLL GR7,0,GR4 ;
選択肢
- 0000000001011000
- 0000000101100011
- 1010000000000000
- 1110100000000000
解法
行番号9開始時のレジスタ格納値は以下のとおりです。
- GR0 : ビット列Bのデータ(1011 0001 1101 0000)
- GR1 : ビット列Bの第4語のアドレス
- GR2 : 7 (第4語の挿入ビット位置)
- GR3 : 12 (挿入ビット列長)
- GR4 : 9 (第4語に挿入されるビット長)
トレースを継続します。
09 LD GR5,GR0 ; GR5 ← GR0=ビット列Bのデータ
14 SRL GR0,0,GR2 ; 第4語の後方に格納する挿入データ生成(右に7ビット論理シフト)
; "1011 0001 1101 0000" → "0000 0001 0110 0011"
16 SLL GR5,0,GR4 ; 第5語の前方に格納する挿入データ生成(左に9ビット論理シフト)
; "1011 0001 1101 0000" → "1010 0000 0000 0000"
⇒ トレースの結果、GR0 = “0000 0001 0110 0011”, GR5 = “1010 0000 0000 0000” で、「イ」「ウ」が正解となります。
10 LD GR6,=#8000 ; GR6 ← #8000
11 SUBA GR3,=1 ; GR3 ← 12 - 1 (マスクデータ作成のためのシフト回数)
12 SRA GR6,0,GR3 ; GR6 ← #FFF0
; ("#8000"を11ビット算術右シフトすることで"#FFF0"になる)
13 LD GR7,GR6 ; GR7 ← #FFF0
15 SRL GR6,0,GR2 ; 上記挿入データに合わせてマスク位置補正(右に7ビット論理シフト)
; "1111 1111 1111 0000" → "0000 0001 1111 1111"
17 SLL GR7,0,GR4 ; 上記挿入データに合わせてマスク位置補正(左に9ビット論理シフト)
; "1111 1111 1111 0000" → "1110 0000 0000 0000"
設問2-e、f
穴埋め箇所
18 LD GR2,0,GR1 ;
19 [ e ] GR6,GR2 ; 第i語のうち
20 [ f ] GR6,GR2 ; ビット列Bを入れる部分を0にする。
21 OR GR2,GR0 ;
22 ST GR2,0,GR1 ;
23 LD GR2,1,GR1 ;
24 [ e ] GR7,GR2 ; 第(i+1)語のうち
25 [ f ] GR2,GR7 ; ビット列Bを入れる部分を0にする。
26 OR GR2,GR5 ;
27 ST GR2,1,GR1 ;
選択肢
- ADDL
- AND
- LD
- OR
- SLL
- SRL
- XOR
解法
行番号18開始時のレジスタ格納値は以下のとおりです。
- GR1 : ビット列Bの第4語のアドレス
- GR0 : ビット列Bの前方データ(0000 0001 0110 0011)
- GR5 : ビット列Bの後方データ(1010 0000 0000 0000)
- GR6 : ビット列Bの後方データのマスク(0000 0001 1111 1111)
- GR7 : ビット列Bの前方データのマスク(1110 0000 0000 0000)
コメントより、行番号19と20でGR2の下位9bitが0クリアされるようなので、 行番号19と20でGR2の下位9bitを0クリアされる命令を選択肢から選びます。
18 LD GR2,0,GR1 ;
19 [ e ] GR6,GR2 ; 第i語のうち
20 [ f ] GR2,GR6 ; ビット列Bを入れる部分を0にする。
通常、GR2の下位9bitを0クリアするには、
; LD GR6,#01FF
XOR GR6,#FFFF ;GR6=FE00
AND GR2,GR6
のように処理しますが、本問では別の方法で実現しています。
選択肢から命令を選び試行してみます。
この試行の結果得られた正解のビット操作を下図に示します。
(第四語には、0011100 101010101が格納されているものとします。)
→ 「イ:AND」「キ:XOR」または「イ:XOR」「キ:AND」が正解となります。
振り返り
出題趣旨
ビット処理は、アセンブラ言語によってよく行われるので、習得しておくことは重要である。 本問は、ビット列の一部を別のビット列で置き換える処理を主題としている。 本問では、ビット列を置き換えるための前処理部分と、実際にビット列を置き換える処理の、大きく二つの部分に分かれている副プログラムを出題した。 設問1でプログラム全体のロジックが理解できたかを問うとともに、設問2でプログラミング能力を問う。
採点講評
問12では、ビット列の一部を別のビット列で置き換えるプログラムについて出題した。 設問1は、a~dの正答率は平均的で、おおむね理解されていた。 設問2は、e及びfの正答率は低く、あまり理解されていなかった。 AND、OR、XORなどのビット処理命令の使い分けがよく理解できていない受験者が多いと思われる。 ビット処理命令を複数個組み合わせた場合に、ビットがどう変化するかを追跡する能力を身につけてほしい。
プログラム詳解
〔プログラム〕
概要
ビット列の一部置き換える副プログラム
入力
- GR0 : ビット列B(左詰め)
- GR1 : ビット列Aの先頭アドレス
- GR2 : 挿入箇所(ビット列Aの先頭からのビット数)
- GR3 : 挿入データ長(ビット数)
○開始
・置換え対象語取得
・置換え対象語での右シフト量算出(例では7)
・置換え対象語+1での左シフト量算出(例では9)
・マスクデータ生成
・置換え対象語に対する置換データ作成
・置換え対象語+1に対する置換データ作成
・置換え対象語に対するマスクデータ作成
・置換え対象語+1に対するマスクデータ作成
・置換え対象語操作((置換え対象語データ AND マスクデータ) XOR 置換え対象語データ)
・置換え対象語+1操作((置換え対象語データ AND マスクデータ) XOR 置換え対象語データ)
○終了
プログラム
01 REPLACE START ;
02 RPUSH ;
03 LD GR4,GR2 ; GR4 ← p
04 SRL GR4,4 ; GR4 ← p/16
05 ADDA GR1,GR4 ; GR1 を置換え対象語(第 i 語)に位置付ける。
06 AND GR2,=#000F ;
07 LD GR4,=16 ;
08 SUBA GR4,GR2 ;
09 LD GR5,GR0 ;
10 LD GR6,=#8000 ;
11 SUBA GR3,=1 ;
12 SRA GR6,0,GR3 ;
13 LD GR7,GR6 ;
14 SRL GR0,0,GR2 ;
15 SRL GR6,0,GR2 ;
16 SLL GR5,0,GR4 ;
17 SLL GR7,0,GR4 ;
18 LD GR2,0,GR1 ;
19 AND GR6,GR2 ; 第i語のうち
20 XOR GR2,GR6 ; ビット列Bを入れる部分を0にする。
21 OR GR2,GR0 ;
22 ST GR2,0,GR1 ;
23 LD GR2,1,GR1 ;
24 AND GR7,GR2 ; 第(i+1)語のうち
25 XOR GR2,GR7 ; ビット列Bを入れる部分を0にする。
26 OR GR2,GR5 ;
27 ST GR2,1,GR1 ;
28 RPOP ;
29 RET ;
30 END ;
平成22春期
概要
解き方
設問1-a
穴埋め箇所
15 JMI BIGEY ; Ex < Ey の場合
19 BIGEY LD GR4,GR5 ; [ a ]
20 SUBL GR5,GR3 ;
21 SRL GR6,0,GR5 ; Mx を調整
選択肢
- ADDL GR4,GR5
- ADDL GR5,GR4
- LD GR4,GR5
- LD GR5,GR4
- SRL GR4,0,GR5
- SRL GR5,0,GR4
解法
本文に以下のように記述されています。
被加数と加数について,いずれか指数の大きい方にもう一方の指数を そろえてから仮数を加算し,
また、「Ex<Eyの場合」や「Mxを調整」のコメントから、行番号19~21の処理は、
Ex<Ey時におけるMxの調整
であると分かります。
Mxの調整といってもピンとこないので、 以下の条件(Ex>Ey)でトレースしてみます。
(分かりやすいように仮数部を整数で表現している)
GR1:25 (→Ex:GR3,GR4=5, Mx:GR6=2)
GR2:43 (→Ey: GR5=3, My:GR7=4)
行番号17では、GR2の指数部を(+2乗(4倍))した補正として、仮数(My)を(-2乗)しています。
04 LD GR4,0,GR1 ;
05 AND GR4,=#00FF ; Ex: X の指数 GR4 ← 5
06 LD GR5,0,GR2 ;
07 AND GR5,=#00FF ; Ey: Y の指数 GR5 ← 3
08 LD GR6,1,GR1 ; Mx: X の仮数 GR6 ← 2
09 LD GR7,1,GR2 ; My: Y の仮数 GR7 ← 4
12 LD GR3,GR4 ; GR3 ← 5
13 CPL GR4,GR5 ; GR4=5 > GR5=3
16 SUBL GR3,GR5 ; GR3 ← GR3(5) - GR5(3) = 2
17 SRL GR7,0,GR3 ; My を調整 GR7を右に2bitシフト
次に、以下の条件(Ex<Ey)でトレースしてみます。
(分かりやすいように仮数部を整数で表現している)
GR1:23 (→Ex:GR3,GR4=3, Mx:GR6=2)
GR2:35 (→Ey: GR5=5, My:GR7=3)
行番号21では、GR1の指数部を(+2乗(4倍))した補正として、仮数(My)を(-2乗)しています。
04 LD GR4,0,GR1 ;
05 AND GR4,=#00FF ; Ex: X の指数 GR4 ← 3
06 LD GR5,0,GR2 ;
07 AND GR5,=#00FF ; Ey: Y の指数 GR5 ← 5
08 LD GR6,1,GR1 ; Mx: X の仮数 GR6 ← 2
09 LD GR7,1,GR2 ; My: Y の仮数 GR7 ← 4
12 LD GR3,GR4 ; GR3 ← 3
13 CPL GR4,GR5 ; GR4=3 < GR5=5
14 JZE MADD ; Ex = Ey の場合
15 JMI BIGEY ; Ex < Ey の場合
19 BIGEY [ a ] ;
20 SUBL GR5,GR3 ; GR5 ← 5 - 3 = 2
21 SRL GR6,0,GR5 ; Mx を調整
[ a ]の処理がなくても正しく仮数部の調整ができているので、 [ a ]は仮数部調整のための処理ではないようです。
各レジスタの設定値を再整理してみます。
Ex>Ey時の設定値 | Ex>Ey時の設定値 | |
---|---|---|
GR1 | 被加数の格納アドレス | ← |
GR2 | 加数の格納アドレス | ← |
GR3 | 大きい方の指数 | 小さい方の指数 |
GR4 | 大きい方の指数 | 小さい方の指数 |
GR5 | 指数差 | 指数差 |
GR6 | Mx | Mx(補正)=My |
GR7 | My(補正)=Mx | My |
⇒ トレースの結果、Ex>Ey時でもEx>Ey時でもGR4に大きい方の指数が設定されるようにする 「ウ LD GR4,GR5」が正解となります。
設問1-b
穴埋め箇所
25 MADD LD GR1,0,GR1 ; X の符号の検査
26 JMI XMINUS ; 負の場合
27 LD GR2,0,GR2 ; Y の符号の検査
28 [ b ] ;
29 LD GR5,GR6 ; X ≧ 0 , Y ≦ 0 の場合
選択肢
- JMI ADDMXY
- JMI XMINUS
- JMI YMINUS
- JPL ADDMXY
- JPL XMINUS
- JPL YMINUS
解法
行番号29のコメントが、「X ≧ 0 , Y ≦ 0 の場合」とあるので、 「JPL ADDMXY」「JPL XMINUS」「JPL YMINUS」が候補となります。
ADDMXY,XMINUS,YMINUSの分岐先に分岐元を調べてみます。
ADDMXYへの分岐元がないので、「JPL ADDMXY」が最も妥当です。
(yの符号判定でXMINUSに分岐するのも、yの符号が正でYMINUSに分岐するのもおかしいので、ADDMXYへの分岐が妥当と考えられます。)
⇒ 「エ:JPL ADDMXY」が正解となります。
設問1-c
トレース対象箇所
25 MADD LD GR1,0,GR1 ; X の符号の検査
26 JMI XMINUS ; 負の場合
27 LD GR2,0,GR2 ; Y の符号の検査
28 JPL ADDMXY ; [ b ]
29 LD GR5,GR6 ; X ≧ 0 , Y ≦ 0 の場合
30 SUBL GR5,GR7 ; Mz ← 調整済 Mx - 調整済 My
31 JUMP SCHECK ;
32 XMINUS LD GR2,0,GR2 ;
33 JMI YMINUS ;
34 LD GR5,GR7 ;
35 SUBL GR5,GR6 ;
36 [ c ] ;
37 YMINUS OR GR4,=#8000 ; Sz に負符号を設定
選択肢
- JOV ADDMXY
- JOV SCHECK
- JPL ADDMXY
- JPL SCHECK
- JUMP ADDMXY
- JUMP SCHECK
解法
選択肢の分岐条件はJOV,JPL,JUMPの三種類、分岐先はADDMXY,SCHECKの二種類。
絞り込みを行うためにソース解析を行ってみる。
ソース解析の結果、xとyの符号を判定し、それぞれの条件において加算処理を行っていることがわかる。
x,yともに正の場合
「行番号28 JPL ADDMXY」で ADDMXYに分岐して、|x| + |y|を実行。
xが正,yが負の場合
「行番号29~30」で |x| + -|y| = |x| - |y|を実行。
xが負,yが正の場合
「行番号34~35」で |y| + -|x| = |y| - |x|を実行。
xが負,yが負の場合
「行番号37 OR GR4,=#8000」で符号を負に設定し、|x| + |y|を実行。
25 MADD LD GR1,0,GR1 ; X の符号の検査
26 JMI XMINUS ; 負の場合
;
; X の符号が正
27 LD GR2,0,GR2 ; X の符号が正の時のY の符号の検査
28 JPL ADDMXY ; X の符号が正、 Y の符号が正 ⇒ XYの加算処理へ
;
; X の符号が正、Y の符号が負
29 LD GR5,GR6 ; GR5 ← |Mx|
30 SUBL GR5,GR7 ; Mz ← |Mx| + -|My| = |Mx| - |My|
31 JUMP SCHECK ; ⇒ 加算結果チェック
;
; X の符号が負
32 XMINUS LD GR2,0,GR2 ; X の符号が負の時のY の符号の検査
33 JMI YMINUS ;
;
; X の符号が負、Y の符号が正
34 LD GR5,GR7 ; GR5 ← |My|
35 SUBL GR5,GR6 ; Mz ← |My| + -|Mx| = |My| - |Mx|
36 [ c ] ;
;
; X の符号が負、Y の符号が負(共に負) Mz ← -|My| + -|Mx| = -(|My|+|Mx|)
37 YMINUS OR GR4,=#8000 ; Sz に負符号を設定
38 ADDMXY LD GR5,GR6 ;
39 ADDL GR5,GR7 ; Mz ← |My| + |Mx|
40 JOV ADJST ; けた上がりがある場合の正規化
41 JUMP NORM ;
42 SCHECK JOV NEGMZ ; Mz の符号を検査
43 JUMP NORM ;
44 NEGMZ OR GR4,=#8000 ; Sz に負符号を設定
45 XOR GR5,=#FFFF ; Mz ← -Mz
46 ADDL GR5,=1 ;
⇒ トレースの結果、「カ:JUMP SCHECK」が正解となります。
設問1-d
トレース対象箇所
47 ;加算結果の正規化
48 NORM LD GR5,GR5 ; ゼロチェック
49 JNZ LOOP ;
50 LD GR4,=0 ;
51 JUMP FIN ;
52 LOOP LD GR5,GR5 ; 正規化完了?
53 JMI FIN ;
54 [ d ] ;
55 SUBL GR4,=1 ;
56 JUMP LOOP ;
選択肢
- SLL GR5,0,GR4
- SLL GR5,1
- SRA GR5,0,GR4
- SRA GR5,1
- SRL GR5,0,GR4
- SRL GR5,1
解法
選択肢の命令は、SLL(論理左シフト),SRA(算術右シフト),SRL(論理右シフト)の三種類、 シフト量は“1”または“GR4”の二種類。
シフト後、JMIで判定(最上位ビットがONか?)で判定しているので、論理左シフトに絞られる。 (算術シフトの場合、最上位ビットは変化しない。論理右シフトの場合、最上位ビットは常に0)
[ d ]の次の「行番号55 SUBL GR4,=1」で指数を1減算しているので、仮数を2倍する必要がある。
⇒ 「イ:SLL GR5,1」が正解となります。
47 ;加算結果の正規化
48 NORM LD GR5,GR5 ; 仮数の加算結果が0か?
49 JNZ LOOP ;
50 LD GR4,=0 ; 0なら、符号部、指数部を0クリアし、処理終了
51 JUMP FIN ;
52 LOOP LD GR5,GR5 ; 正規化完了?
53 JMI FIN ; 仮数の最上位ビットがONなら終了
54 [ d ] ;
55 SUBL GR4,=1 ; 指数を1減算
56 JUMP LOOP ;
設問1-e
穴埋め箇所
57 ADJST SRL GR5,1 ;
58 OR GR5,=#8000 ; Mz の最上位ビットを 1 に設定
59 [ e ] ;
選択肢
- ADDL GR4,=1
- ADDL GR5,=1
- SLL GR4,1
- SLL GR5,1
- SUBL GR4,=1
- SUBL GR5,=1
解法
選択肢の命令は、ADDL,SLL(論理左シフト),SUBLの三種類 操作対象は、GR4またはGR5。
57 ADJST SRL GR5,1 ;
58 OR GR5,=#8000 ; Mz の最上位ビットを 1 に設定
59 [ e ] ;
解答 e=ア カ
設問2-
穴埋め箇所
選択肢
解法
⇒
別解
⇒
振り返り
出題趣旨
ビット処理は、アセンブラ言語によってよく行われるので、習得しておくことは重要である。 本問は、ビット列を逆転する処理を主題としている。 本問では、長さ1語のビット列を逆転するプログラム1をまず出題した。 次にプログラム1を利用して複数語からなるビット列を逆転するプログラム2、1語に満たない部分ビット列を逆転するプログラム3について出題した。 設問1でビット処理に関する基礎的なプログラミング能力を問い、設問2、設問3でプログラミングの応用力を問う。
採点講評
問12では、簡易な浮動小数点形式を基に、32ビット浮動小数点数の加算を行うプログラムについて出題した。 設問1の正答率は低く、あまり理解されていなかった。 bではウ、cではウ又はオと誤って解答した受験者が見受けられた。 プログラムの説明から、浮動小数点数の加算がどのように行われるのかを理解して処理を追跡すれば、正答できた。 eは解答が分散した。 けた上がりがある場合の処理であり、正規化が必要であることが理解できれば、正答できた。 設問2の正答率は低く、あまり理解されていなかった。 オと誤って解答した受験者が見受けられた。 加数Yの符号だけを反転させればよいことを理解できれば、正答できた。 語のビットがどのように変化していくのかを考えながら処理を追跡することが重要である。
プログラム詳解
〔プログラム〕
概要
浮動小数点数の加算を行う副プログラム
入力
- GR1 : 被加数X 格納領域の先頭番地
- GR2 : 加数Y 格納領域の先頭番地
- GR3 : 結果Z 格納領域の先頭番地
プログラム
01 FADD START ; Z ← X + Y
02 RPUSH ;
03 PUSH 0,GR3 ; 結果 Z の格納領域の先頭番地を退避
04 LD GR4,0,GR1 ;
05 AND GR4,=#00FF ; Ex: X の指数
06 LD GR5,0,GR2 ;
07 AND GR5,=#00FF ; Ey: Y の指数
08 LD GR6,1,GR1 ; Mx: X の仮数
09 LD GR7,1,GR2 ; My: Y の仮数
10 ; 加算前の準備 (指数をそろえる)
11 ; GR4 ← max(Ex,Ey) , GR6 ← 調整済 Mx , GR7 ← 調整済 My
12 LD GR3,GR4 ;
13 CPL GR4,GR5 ;
14 JZE MADD ; Ex = Ey の場合
15 JMI BIGEY ; Ex < Ey の場合
16 SUBL GR3,GR5 ;
17 SRL GR7,0,GR3 ; My を調整
18 JUMP MADD ;
19 BIGEY LD GR4,GR5 ;
20 SUBL GR5,GR3 ;
21 SRL GR6,0,GR5 ; Mx を調整
22 ; 符号を考慮した仮数の加算
23 ; Sz: Z の符号 , Ez: Z の指数 , Mz: Z の仮数
24 ; GR4 ← (Sz,Ez) , GR5 ← Mz
25 MADD LD GR1,0,GR1 ; X の符号の検査
26 JMI XMINUS ; 負の場合
27 LD GR2,0,GR2 ; Y の符号の検査
28 JPL ADDMXY ;
29 LD GR5,GR6 ; X ≧ 0 , Y ≦ 0 の場合
30 SUBL GR5,GR7 ; Mz ← 調整済 Mx - 調整済 My
31 JUMP SCHECK ;
32 XMINUS LD GR2,0,GR2 ;
33 JMI YMINUS ;
34 LD GR5,GR7 ;
35 SUBL GR5,GR6 ;
36 JUMP SCHECK ;
37 YMINUS OR GR4,=#8000 ; Sz に負符号を設定
38 ADDMXY LD GR5,GR6 ;
39 ADDL GR5,GR7 ; Mz ← 調整済 Mx + 調整済 My
40 JOV ADJST ; けた上がりがある場合の正規化
41 JUMP NORM ;
42 SCHECK JOV NEGMZ ; Mz の符号を検査
43 JUMP NORM ;
44 NEGMZ OR GR4,=#8000 ; Sz に負符号を設定
45 XOR GR5,=#FFFF ; Mz ← -Mz
46 ADDL GR5,=1 ;
47 ;加算結果の正規化
48 NORM LD GR5,GR5 ; ゼロチェック
49 JNZ LOOP ;
50 LD GR4,=0 ;
51 JUMP FIN ;
52 LOOP LD GR5,GR5 ; 正規化完了?
53 JMI FIN ;
54 SLL GR5,1 ;
55 SUBL GR4,=1 ;
56 JUMP LOOP ;
57 ADJST SRL GR5,1 ;
58 OR GR5,=#8000 ; Mz の最上位ビットを 1 に設定
59 ADDL GR4,=1 ;
60 FIN POP GR3 ;
61 ST GR4,0,GR3 ; 結果 Z の格納
62 ST GR5,1,GR3 ;
63 RPOP ;
64 RET ;
65 END ;
平成22秋期
概要
解き方
設問1-a
穴埋め箇所
選択肢
解法
⇒
別解
⇒
設問1-b
穴埋め箇所
選択肢
解法
⇒
別解
⇒
設問2-c
穴埋め箇所
選択肢
解法
⇒
別解
⇒
設問2-d
穴埋め箇所
選択肢
解法
⇒
別解
⇒
設問3-e
穴埋め箇所
選択肢
解法
⇒
別解
⇒
設問3-f
穴埋め箇所
選択肢
解法
⇒
別解
⇒
振り返り
出題趣旨
ビット処理は、アセンブラ言語によってよく行われるので、習得しておくことは重要である。 本問は、ビット列を逆転する処理を主題としている。 本問では、長さ1語のビット列を逆転するプログラム1をまず出題した。 次にプログラム1を利用して複数語からなるビット列を逆転するプログラム2、1語に満たない部分ビット列を逆転するプログラム3について出題した。 設問1でビット処理に関する基礎的なプログラミング能力を問い、設問2、設問3でプログラミングの応用力を問う。
採点講評
問12では、ビット列のビットの並びを逆転するプログラムについて出題した。 設問1の正答率は平均的で、おおむね理解されていた。 設問2の正答率は低く、あまり理解されていなかった。 c及びdではオと誤って解答した受験者が見受けられた。 ループが二つ存在し、1番目のループでは語単位で並びを逆転し、2番目のループで各語のビットの並びを逆転している。 このことが理解できれば、正答できた。 設問3の正答率はいずれも平均的で、おおむね理解されていた。 プログラム全体の流れを理解することが重要である。
プログラム詳解
〔プログラム1〕
概要
入力
概略フロー
○開始
○終了
注意点
プログラム
01 REVRS START ;
02 RPUSH ;
03 LD GR4,=0 ; 結果のビット列を初期化
04 LAD GR2,15 ; ループカウンタ
05 LD GR3,0,GR1 ; GR3 ← ビット列
06 LOOP SLL GR4,1 ; 結果のビット列を左シフト
07 SRL GR3,1 ; 元のビット列を右シフト
08 JOV ON ;
09 JZE FIN1 ; 元のビット列の残りのビットはすべてゼロ
10 JUMP OFF ;
11 ON OR GR4,=#0001 ;
12 OFF SUBA GR2,=1 ;
13 JMI FIN2 ; 16 ビット処理済み
14 JUMP LOOP ;
15 FIN1 SLL GR4,0,GR2 ; 結果のビット列を残りのビット数だけシフト
16 FIN2 ST GR4,0,GR1 ;
17 RPOP ;
18 RET ;
19 END ;
〔プログラム2〕
概要
入力
概略フロー
○開始
○終了
注意点
プログラム
01 LREVRS START ;
02 RPUSH ;
03 LD GR3,GR1 ;
04 LD GR4,GR2 ;
05 SUBA GR4,=1 ;
06 JZE LOOP2 ;
07 ADDA GR4,GR1 ;
08 LOOP1 LD GR5,0,GR3 ;
09 LD GR6,0,GR4 ; GR3 が指す語と GR4 が指す語の内容を
10 ST GR5,0,GR4 ; 入れ替える
11 ST GR6,0,GR3 ;
12 LAD GR3,1,GR3 ; GR3 を次の語に位置付ける
13 LAD GR4,-1,GR4 ; GR4 を一つ前の語に位置付ける
14 CPA GR3,GR4 ;
15 JMI LOOP1 ;
16 LOOP2 CALL REVRS ;
17 LAD GR1,1,GR1 ;
18 SUBA GR2,=1 ;
19 JNZ LOOP2 ;
20 FIN3 RPOP ;
21 RET ;
22 END ;
〔プログラム3〕
概要
入力
概略フロー
○開始
○終了
注意点
プログラム
01 PREVRS START ;
02 RPUSH ;
03 LD GR4,0,GR1 ; ビット列を保存
04 CALL REVRS ; ビット列のビットの並びを逆転
05 LD GR5,0,GR1 ; GR5 ← 逆転したビット列
06 LD GR6,=16 ;
07 SUBA GR6,GR3 ; GR6 ← 16 - q
08 SRL GR5,0,GR2 ; 逆転した部分ビット列αを右端に移動
09 SLL GR5,0,GR6 ; 逆転した部分ビット列αを左端に移動
10 SRL GR5,0,GR2 ; 逆転した部分ビット列αを p ビットに移動
11 LD GR6,=#8000 ;
12 SRA GR6,-1,GR3 ; q ビット連続した1の並びを作成
13 SRL GR6,0,GR2 ;
14 XOR GR6,=#FFFF ;
15 AND GR6,GR4 ; 元のビット列中の部分ビット列αにゼロを設定
16 OR GR6,GR5 ;
17 ST GR6,0,GR1 ;
18 RPOP ;
19 RET ;
20 END ;
あとがき
履歴
更新内容 | |
---|---|
2020.12 | 新規作成 |
0 件のコメント:
コメントを投稿