この記事では、過去問のアセンブラの問題に載っているプログラムを実際に自分の環境で作成して動かすのに使ったコードと、トレースのノートを掲載しています。
この記事を通してアセンブラだけでなくアルゴリズムのトレース力向上にもお役立て下さい。
アセンブラ過去問プログラミング
アセンブラ自作サンプルへ
基本情報技術者試験トップへ
令和2年度(令和3年1月合格報告)
シミュレーターと過去問を解くまでの勉強に使った参考書はこちらです
図形の回転の問題です。
設問1では漢数字の「五」を時計回りに回転させます。
このプログラムでは回転前の文字列が格納されている領域をBEFORE、回転後の領域をAFTERとしています。
GR1に回転前の先頭アドレス、GR2に回転後の結果格納領域の先頭アドレスを設定して、副プログラムを呼び出します。
回転前の先頭の語は、黒が1、白が0なので、1111111111111100となって、16進数ではFFFCです。それを16語分設定しました。
まず、設問1のプログラムを実行して見ます。
このようになりました。
プログラムとトレースのノートです。
プログラムは、メインプログラムから設問のプログラムとドット絵表示用のプログラムを呼び出しています。
;呼び出し元
MAIN START
RPUSH
LAD GR1,BEFORE ;回転前の領域の先頭アドレス
LD GR3,=16 ;ドット絵の表示用のループカウンタ
LOOPX
CALL DOT ;表示用プログラム「DOT」を呼び出す
LAD GR1,1,GR1 ;回転前の領域のアドレス+1で次の語へ
SUBL GR3,=1 ;処理待ち語数を減らす
JPL LOOPX ;16語まで繰り返す
OUT LINE,LLEN ;回転前と回転後のドット絵の区切り線
LAD GR1,BEFORE ;回転前の領域の先頭アドレス
LAD GR2,AFTER ;回転後の結果格納領域の先頭アドレス
CALL ROTATE ;設問1のプログラムを呼び出す
LAD GR1,AFTER ;回転処理後の先頭アドレスを移す
LD GR3,=16 ;ドット絵の表示用のループカウンタ
LOOPZ CALL DOT ;表示用プログラム「DOT」を呼び出す
LAD GR1,1,GR1 ;回転後の領域アドレス+1
SUBL GR3,=1
JPL LOOPZ
RPOP
RET
BEFORE DC #FFFC ;回転前の元のドット絵の先頭アドレス(1語目)
DC #FFFC
DC #FFFC
DC #0700
DC #0700
DC #0700
DC #FFFC
DC #FFFC
DC #FFFC
DC #071C
DC #071C
DC #071C
DC #FFFF
DC #FFFF
DC #FFFF
DC #0000
LINE DC ‘——————–‘
LLEN DC 20
AFTER
DC #0000 ;回転後の結果格納領域の先頭アドレス(1語目)
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
DC #0000
PRINT DS 16
LEN DC 16
;設問1のプログラム
ROTATE RPUSH
LD GR3,=16 ;処理する語数
LOOP1 LD GR4,=16 ;処理中の語のビット数
LD GR5,GR2 ;GR5←結果の領域のアドレス
LD GR6,0,GR1 ;GR6←元の図形の先頭語の内容
LOOP2 LD GR7,0,GR5 ;GR7←結果の領域の1語の内容
SRL GR7,1 ;結果のビットを右側へ
SLL GR6,1 ;「設問2」回転の変換をするビットを左にシフトで落とす
JOV ON ;1がこぼれたら分岐
JUMP CONT ;結果格納処理へ
ON OR GR7,=#8000 ;回転前の1を回転後へ転送
CONT ST GR7,0,GR5 ;処理した1語を結果の領域に格納
LAD GR5,1,GR5 ;結果格納領域を次の語に進める
SUBA GR4,=1 ;処理待ちビット数を減らす
JNZ LOOP2 ;処理中なら分岐
LAD GR1,1,GR1 ;次の語へ
SUBA GR3,=1 ;処理待ち語数を減らす
JNZ LOOP1 ;処理中の語があれば分岐
RPOP
RET
;ドット絵表示プログラム
DOT RPUSH
LAD GR6,PRINT ;表示用の領域の先頭アドレス
LD GR4,GR1 ;表示するドット絵の先頭アドレスを読み込む
LD GR3,=16 ;処理待ちビット数
LD GR4,0,GR4 ;表示する語を読み込む
LOOPY
SLL GR4,1 ;表示するビットを左シフトで落とす
JOV ONE ;1だったら分岐
LD GR5,=’◯’ ;0だったら白抜き丸
JUMP NEXT
ONE LD GR5,=’●’ ;1だったら黒抜き丸
NEXT
ST GR5,0,GR6 ;表示領域に丸を格納する
LAD GR6,1,GR6 ;表示領域を次の語へ
SUBL GR3,=1 ;処理待ちビットカウンタ
JPL LOOPY
OUT PRINT,LEN ;表示する
RPOP
RET
END
設問2では、プログラムの1部のシフトの向きを左から右シフトに変えます。
その場合での実行結果です。
設問3では、プログラムの一部を変えて、指定したビット分だけ回転させます。
ここでは回転させるビット数(n×n)を、5×5として見ました。
実行結果、プログラム、ノートです。
;設問3のプログラム
ROTATE RPUSH
LD GR3,=5 ;n(回転する部分)を5とする
ST GR3,N ;nを保存
LD GR4,GR3 ;GR4←n
LD GR5,GR1 ;GR5←元の図形のアドレス
LD GR6,GR2 ;GR6←結果の領域のアドレス
LD GR7,=16 ;回転しない部分の計算準備
SUBA GR7,GR3 ;GR7←16-n
SHIFT LD GR0,0,GR5 ;GR0←元の図形の1語の内容
SLL GR0,0,GR3 ;回転しない部分を左シフトで残す
ST GR0,0,GR6 ;結果の領域←GR0
LAD GR5,1,GR5 ;元の図形の1語のアドレス更新
LAD GR6,1,GR6 ;結果の領域の1語のアドレス更新
SUBA GR4,=1 ;n語処理済み?
JNZ SHIFT
COPY SUBA GR7,=1 ;残りの語の内容を結果の領域に複写
JMI LOOP1 ;処理待ち語がなくなったら分岐
LD GR0,0,GR5 ;回転しない語を読み込む
ST GR0,0,GR6 ;結果領域へ格納
LAD GR5,1,GR5
LAD GR6,1,GR6
JUMP COPY
N DS 1
LOOP1 LD GR4,N
今度受けるので、自分の勉強になりました。
どなたかのお役に立てたらうれしいです。
この記事を書くのに丸2日かかったので、
誰も見ていなかったら泣いちゃいます( ;∀;)
どなたか見ている人いますか?いたら手を振って下さい(=^・^=)