平成24秋 問12 アセンブラ のプログラミング(コメント、トレースのノート付き)

この記事では、過去問のアセンブラの問題に載っているプログラムを実際に自分の環境で作成して動かすのに使ったコードと、トレースのノートを掲載しています。
この記事を通してアセンブラだけでなくアルゴリズムのトレース力向上にもお役立て下さい。

アセンブラ過去問プログラミング
アセンブラ自作サンプルへ
基本情報技術者試験トップへ
令和2年度(令和3年1月合格報告)

シミュレーターと過去問を解くまでの勉強に使った参考書はこちらです

多項式の値を求める問題です。
この問題の具体例として、問題文の具体例よりも簡単になるように、計算しやすい例を用いました。
xを2、n=3として、
(2^3)+(2^2)+(2^1)+(2^0)=8+4+2+1=15を求めます。

では、プログラム1からトレースして行きます。

メインプログラムでx=2をGR2に、n=3をGR1に設定しました。

ここからプログラム1のPOLYを呼び出します。
演算結果を格納するGR4が初期化されました。

かける回数のカウンタが入りました。

被乗数(かけられる数)が初期化されました。

かけ算プログラムMULTが呼び出されました。
1×2=2が求まれれます。
被乗数(かけられる数)が入りました。
(乗数(かける数)はGR2に入っています。)

かけ算の結果が初期化されました。

乗数を退避して、下一桁が0かどうか調べます。

2は2進数で0010なので、0001をかけて下一桁が0であることが
判明しました。

被乗数が左シフト、乗数が右シフトされました。

乗数が退避されました。

演算結果が格納されました。

被乗数が左シフト、乗数が右シフトされました。

呼び出し元に戻りました。
かける回数が1つ減って2になりました。

かけられる数、かける数が設定され、2×2=4が求まります。
MULTが呼び出されました。
(かけ算処理は省略)

呼び出し元に戻って、かける回数が1回減りました。

かけられる数、かける数が設定され、4×2=8が求まります。
MULTが呼び出されました。
(かけ算処理は省略)

呼び出し元に戻りました。
GR3が0になり、かけ算処理が終わり、2の3乗の2×2×2=8がGR4に加算されました。

次は、2の2乗の4を求めてGR4に加算します。
(かけ算処理省略)

2の3乗の8に2の2乗の4が加算されて12(000C)になりました。

12(000C)に2の1乗の2が加算されて14(000E)になりました。

14(000E)に2の0乗の1が加算されて15(000F)になりました。

マイナスになったので多項式の演算処理が終了しました。

GR0に演算結果が求まりました。

プログラム1、プログラム2、トレースのノートはこちらになります。

;メインプログラム
MAIN START
RPUSH

;F(x,n)は問題文より少し簡単な「xに2」、「nに3」を設定する
LD GR2,X
LD GR1,N
CALL POLY
RPOP
RET
X DC 2
N DC 3
;プログラム1
POLY RPUSH
LD GR4,=0 ;計算結果格納レジスタの初期化
LP1 LD GR3,GR1 ;nをカウンタとして加算乗算に利用
JMI FIN ;0乗まで計算するのでマイナスになったら分岐
LD GR0,=1 ;x^nの計算開始(初期化)
LP2 LD GR3,GR3 ;0乗まで計算しましたか?
JZE BRK ;x^nの計算終了ならBRKへ
CALL MULT ;(GR0)←(GR0)×(GR2)
LAD GR3,-1,GR3 ;かける回数のカウンタを1つ減らす
JUMP LP2
BRK ADDL GR4,GR0 ;計算結果格納レジスタにx^nの値を加算
LAD GR1,-1,GR1 ;nから1を減じ、低次の項の計算へ
JUMP LP1
FIN LD GR0,GR4 ;計算結果を読み込む
RPOP
RET


;プログラム2
MULT ;シフトによる乗算
RPUSH
LD GR1,GR0
LD GR0,=0 ;乗算結果の初期化
LD GR2,GR2 ;乗数(かける数)は0ですか?
LP JZE FIN2
LD GR3,GR2 ;乗数を退避
AND GR3,=#0001 ;最下位ビットのチェック
JZE CONT
ADDL GR0,GR1
CONT
SLL GR1,1
SRL GR2,1
JUMP LP
FIN2 RPOP
RET
END

では、再帰呼び出しによるプログラム3のトレースを行います。
xとnが入ってPOLY2を呼び出します。

再帰処理が始まります。
スタックに呼び出し元アドレスが積まれました。

F(x,n)=x×F(x,n-1)+1 (n>=1)のn-1にあたるnの減算処理が行われました。

呼び出し元の1つ先のアドレスがスタックに積まれて再帰呼び出しに行きました。

n-1が行われました。

呼び出し元の1つ先のアドレスがスタックに積まれて再帰呼び出しに行きました。

n-1が行われました。

呼び出し元の1つ先のアドレスがスタックに積まれて再帰呼び出しに行きました。

n=0の時の処理が実行されました。

スタックから1つ取り出されて呼び出し元の1つ先のアドレスに行きました。


1×2が設定されMULTを呼び、かけ算処理を行います。

1×2の計算結果の2が求まりました。

スタックから1つ取り出されて呼び出し元の1つ先のアドレスに行きました。


2に1が加算され3になり、MULTを読んでかけ算処理を行います。

演算結果の2×3の6が求まりました。

1が加算され7になりました。

スタックから1つ取り出されて呼び出し元の1つ先のアドレスに行きました。
MULTを読んでかけ算処理を行います。

7×2=14が実行されました。

1が加えられました。

スタックから1つ取り出されて呼び出し元の1つ先のアドレスに行きました。

以上で終了になります。

プログラム1、プログラム2、トレースのノートはこちらになります。

;メインプログラム
;F(x,n)は問題文より少し簡単な「xに2」、「nに3」を設定する

MAIN START
RPUSH
LD GR2,X
LD GR1,N
CALL POLY2
RPOP
RET
X DC 2
N DC 3
POLY2
RPUSH
CALL RSUB ;再帰処理の本体を呼ぶ
RPOP
RET ;主プログラムに戻る
RSUB
LD GR1,GR1 ;n=0?
JNZ CONT3 ;n<>0ならCONT3へ
LD GR0,=1 ;GR0←F(x,0)の値(=1)
RET
CONT3 LAD GR1,-1,GR1 ;再帰呼び出しnの回数を1減らす
CALL RSUB ;F(x,n-1)を計算
CALL MULT ;かけ算処理
ADDL GR0,=1 ;被乗数(かけられる数に1加える)
RET


;プログラム2
MULT ;シフトによる乗算
RPUSH
LD GR1,GR0
LD GR0,=0 ;乗算結果の初期化
LD GR2,GR2 ;乗数(かける数)は0ですか?
LP JZE FIN2
LD GR3,GR2 ;乗数を退避
AND GR3,=#0001 ;最下位ビットのチェック
JZE CONT
ADDL GR0,GR1
CONT
SLL GR1,1
SRL GR2,1
JUMP LP
FIN2 RPOP
RET
END

今度受けるので、自分の勉強になりました。
どなたかのお役に立てたらうれしいです。
この記事を書くのに6時間かかったので、
誰も見ていなかったら泣いちゃいます( ;∀;)
どなたか見ている人いますか?いたら手を振って下さい(=^・^=)
要領悪すぎにゃ~~~~~~( ;∀;)(=^・^=)( ;∀;) (^O^)/

シミュレーターと過去問を解くまでの勉強に使った参考書はこちらです

アセンブラ過去問プログラミング
アセンブラ自作サンプルへ
基本情報技術者試験トップへ
息抜きに、写真で癒し(=^・^=)