;２０１８年平成３０年度春の試験問題（修正版）
;Visi作者によるソースコード修正版
;設問3. シフト命令を使った乗算
MAIN START
  LAD GR1,STR
  CALL MULT
  ST GR0,ANS
  RET
STR DC ' 332  58  .'
ANS DS 1
  END
;-------------
MULT START
  RPUSH
  LAD GR2,CTBL
  CALL GETWD
  LD GR4,0,GR2 ; GR4 <-- 被乗数
  LD GR5,1,GR2 ; GR5 <--   乗数
  LD GR0,=0    ; GR0 <-- 乗算結果を初期化
  LD GR5,GR5
LP JZE FIN ; 問e オ　乗数がゼロならば終了
  LD GR3,GR5
  AND GR3,=#0001 ;　乗数の最下位ビットのチェック
  JZE NEXT
  ADDL GR0,GR4
NEXT SLL GR4,1 ;　被乗数を１ビット左論理シフト
  SRL GR5,1 ; 問f　オ
  JUMP LP
FIN RPOP
  RET
CTBL DS 3 ; GTWD用管理テーブル
  END
;------------------------------------
GETWD START
  RPUSH
  LD GR6,GR1 ; 文字列の先頭アドレス
  LD GR7,GR2 ; 管理テーブルの先頭アドレス
  LD GR3,=-1 ; 数字列の処理状態フラグの初期化
  LAD GR6,-1,GR6
LP LAD GR6,1,GR6 ;
  LD GR4,0,GR6 ; １文字の取り出し
  CPL GR4,='.'
  JZE FIN
  CPL GR4,=' '
  JNZ NUM
  CALL SETWD
  JUMP LP
NUM LD GR3,GR3 ; 数字列の処理中？
  JZE LP
  LD GR3,=0    ; 次の数字列の処理開始
  LD GR1,GR6   ; 数字列の先頭アドレスを退避
  JUMP LP
FIN CALL SETWD
  LD GR2,=-1
  ST GR2,0,GR7 ;数値の終わりを示す印を格納
  RPOP
  RET
  END
;------
SETWD START
  LD GR3,GR3
  JNZ FIN2 ; 問c　イ
  LD GR2,GR6
  SUBL GR2,GR1
  CALL DTOB   ; 数字列を数値に変換
  ST GR0,0,GR7
  LD GR3,=-1  ; 数字列の処理中状態を解除
  LAD GR7,1,GR7 ; 問d   エ
FIN2 RET
  END
;-----------------------------
DTOB START
  RPUSH
  ADDL GR2,GR1
  LAD GR0,0     ; 戻り値の初期化
LP CPL GR1,GR2  ; 変換終了？
  JZE FIN
  LD GR4,0,GR1  ; 数字一文字の取り出し
  SUBL GR4,='0' ; 一桁を数値に変換
  SLL GR0,1     ; GR0 を１０倍してGR4を加算
; 左１シフトして２倍となる。
  LD GR5,GR0    :一時的にGR5に格納
  SLL GR5,2     ; 問題 a 答え オ
;２倍した後、４倍したので８倍となった。
  ADDL GR0,GR5
;２倍の値GR0と８倍の値GR5を加算して
; GR0は１０倍となる。
  ADDL GR0,GR4
  LAD GR1,1,GR1
  JUMP LP
FIN RPOP
  RET
  END
;----------------------
