基本情報技術者試験 アセンブラ 平成21年春期

 

平成21年春期

概要

事前知識として、
- 「アセンブラにおける乗算方法
- 「アセンブラにおける32bitの加算方法
- 「連続する32bitデータのシフト操作
を理解しておくと容易に解答できます。

解き方

設問1-a

穴埋め箇所

07  LP       SRL   GR2,1                ; 乗数を1ビット右にシフト  
08           [  a  ]                    ;   
09           JZE   FIN                  ;   
10           JUMP  NEXT                 ; 加算処理をスキップ  

選択肢

  1. JMI ADD32
  2. JMI LP
  3. JOV ADD32
  4. JOV LP
  5. JPL ADD32
  6. 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     

選択肢

  1. JMI ADJ1
  2. JMI ADJ2
  3. JOV ADJ1
  4. JOV ADJ2
  5. JPL ADJ1
  6. 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                   ;   

選択肢

  1. JNZ LP
  2. JPL LP
  3. JZE LP
  4. SLL GR5,1
  5. SRA GR5,1
  6. 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            ;   

選択肢

  1. LD GR1,0,GR1
  2. LD GR1,0,GR2
  3. LD GR1,1,GR1
  4. LD GR2,0,GR1
  5. LD GR2,0,GR2
  6. LD GR2,1,GR1
解法
副プログラム(MULS)のインプットは以下のとおり。(本文の説明より)
  • GR1 : 被乗数格納域アドレス
  • GR2 : 乗数
  • GR3 : 積(計算結果)格納域アドレス
行番号06「CALL MULS」実施前のGR1~GR3の状態
  • GR1 : 被乗数格納域アドレス
  • GR2 : 乗数(行番号05にて乗数の下位語格納)
  • GR3 : 積(計算結果)格納域アドレス
行番号10「CALL MULS」実施前のGR1~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            ;   

選択肢

  1. LD GR6,0,GR1
  2. LD GR6,0,GR2
  3. LD GR6,0,GR3
  4. LD GR6,1,GR1
  5. LD GR6,1,GR2
  6. 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 件のコメント:

コメントを投稿

基本情報技術者試験 アセンブラ(CASL) 原稿 20210529

  基本情報技術者試験 アセンブラ(CASL) 簡単に5割 平成21年春期,平成21年秋期 平成21春期 平成21秋期 平成22春期 平成22秋期 平成21春期 概要 解き方 設問1-a 設問1-b 設問1-c 設問2-d...