平成21年春期
概要
事前知識として、
- 「アセンブラにおける乗算方法」
- 「アセンブラにおける32bitの加算方法」
- 「連続する32bitデータのシフト操作」
を理解しておくと容易に解答できます。
解き方
設問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ビット右にシフト
|▲オーバーフロー発生? /*シフト前の最下位ビットがONか?*/
||加算処理実施 /*計算結果 ← 計算結果 + 被乗数*/
|▼
|▲シフト後ゼロ? /*乗算終了?*/
||計算処理終了
|▼
|被乗数を1ビット左にシフト
■
⇒ オーバーフロー発生時に加算処理に分岐する、「ウ:JOV 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〕
概要
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 ; [ a ]
09 JZE FIN ;
10 JUMP NEXT ; 加算処理をスキップ
11 ADD32 ADDL GR6,GR4 ; 32ビット+32ビット→32ビット
12 ADDL GR7,GR5 ;
13 JOV ADJ1 ; [ b ]
14 JUMP NEXT ;
15 ADJ1 ADDL GR6,=1 ; けた上げ処理
16 NEXT SLL GR4,1 ; 被乗数(32ビット)を1ビット左にシフト
17 SLL GR5,1 ; [ c ]
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 ; [ d ]
09 LAD GR3,SV ; 結果の格納先として作業領域を設定
10 CALL MULS ; 被乗数×乗数上位語→積(B)
11 LD GR6,1,GR3 ; [ e ]
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年度春季
処理方法
① 計算結果に0を設定
② 乗数の最下位ビットが“1”か?
(右に1ビットシフトしオーバーフロー発生有無を確認する)
③ シフト後の乗数が0なら処理を終了する。
④ 乗数の最下位ビットが“1”(オーバーフロー発生)なら、計算結果に被乗数を加算する。
⑤ 被乗数を左に1ビットシフトし、新たな被乗数とする。
⑥ ②~⑤の処理を繰り返す。
「00001100 × 00001001 」時、以下のように計算しています。
00001100 × 00001001
= 00001100 × (00000001 + 00001000)
= 00001100 × 00000001
+ 00001100 × 00001000
= 00001100 × 00000001
+ 00001100 × 1000 ; 被乗数を左に3bitシフト
× 00001000 × 1/1000 ; 乗数を右に3bitシフト
アセンブラにおける32bitの加算方法
出題年度 平成21年度春季
処理方法
① 下位16ビットを加算/減算
② 上位16ビットを加算/減算
③ ①でオーバーフロー発生時、②の結果に反映する。
連続する32bitデータのシフト操作
出題年度 平成21年度春季
処理方法
左シフト
① 上位16ビットを1ビットシフト
② 下位16ビットを1ビットシフト
③ ②でオーバーフロー発生なら、上位16ビットの最下位ビットに“1”を設定。
右シフト
① 下位16ビットを1ビットシフト
② 上位16ビットを1ビットシフト
③ ②でオーバーフロー発生なら、下位16ビットの最上位ビットに“1”を設定。
0 件のコメント:
コメントを投稿