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

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

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

割り算プログラムの問題です。
具体例として、被除数(以下、割られる数)を50、除数(以下、割る数)を20とします。そうすると、商が2、余りが10になります。

入力
GR1:#0000(割られる数の上位語)
GR2:#0032(割られる数の下位語で50)
GR3:割る数が格納してある領域「WARU」の先頭アドレス「WARU+0」
GR3+1:WARU+1
割る数には20の16進数表記#0014を入れました。

このプログラム1を実行すると、

出力
GR1:#0000(商の上位語)
GR2:#0002(商の下位語で2)
GR4:#0000(余りの上位語)
GR5:#000A(余り語下位語で10)

となります。

では、ステップ実行していきます。
実行すると、割る数の上位語下位語が入りました。下位語は20の16進数表記、#0014が入りました。

次に、割られる数の上位語#0000、下位語50の#0032が入りました。

ここで、メインプログラムから割り算プログラムのDIVが呼び出されました。
割れれる数の上位語下位語がそれぞれ退避されました。

商の上位語下位語が初期化されました。

ループに入り、割られる数の上位語下位語が退避されました。
これは余りを求めるのに使います。

割り算実行前の商が上位語、下位語ともに入りました。

1回目の割り算処理が実行されました。
50から20を引いて30になり、その16進数の#001Eが入りました。

1回目の割り算処理実行後の結果が退避されました。

商がカウントアップされました。

30から20を引いた余りの10が求まりました。

2回目の割り算処理実行後の結果が退避されました。

商がカウントアップされました。

余りの10から割る数の20を引いたらオーバーフローしました。

プログラム1が終わりました。

プログラム1はこちらになります。

トレースに使ったノートはこちらになります。

;平成23年秋…割り算プログラム1
;呼び出し元のメインプログラム
MAIN START
RPUSH
LD GR1,=#0000 ;割られる数の上位語
LD GR2,=#0032 ;その下位語で50
LAD GR3,WARU ;結果領域先頭後
CALL DIV
RPOP
RET
WARU DC #0000 ;割る数上位語
DC #0014 ;割る数下位語で20



;プログラム1
DIV
PUSH 0,GR6
PUSH 0,GR7
LD GR6,GR1 ;割られる数の上位語
LD GR7,GR2 ;割られる数の下位語
LD GR1,=#FFFF ;商の初期化
LD GR2,=#FFFF
LP LD GR4,GR6 ;割られる数の上位語
LD GR5,GR7 ;割られる数の下位語
ADDL GR2,=1 ;商のカウントアップ
JOV ADJ1 ;桁上り処理へジャンプ
JUMP CONT ;割り算実行
ADJ1 ADDL GR1,=1 ;桁上り処理実行
CONT SUBL GR6,0,GR3 ;引き算しながら割り算していく
JOV FIN
SUBL GR7,1,GR3 ;引き算しながら割り算していく
JOV ADJ2
JUMP LP
ADJ2 SUBL GR6,=1 ;繰り下がり処理
JOV FIN
JUMP LP
FIN POP GR7
POP GR6
RET
END

次にプログラム2、3では、割り算プログラムのプログラム1、DIVを利用して、
10進数の数字列に変換します。

GR1:#0000(変換する数の上位語)
GR2:#054D(変換する数の下位語、10進数で1357)

10000を16進数に直すと#2710、1000は#03E8、100は#0064、10は#000Aになります。
それをUDATに設定します。
結果を出力ウィンドウに表示します。

では、プログラム2を含めたステップ実行をして行きます。
丁寧にかつ、冗長な繰返しの所は要所要所省きながら行いました。

主記憶に1桁ずつ格納する結果領域KEKKAが用意されました。

数字列にする(割られる)数の上位語下位語が設定されました。
プログラム2、BTOD2が呼び出されました。

結果領域の先頭、末尾アドレスが入りました。

プログラム1、DIVが呼び出されました。

1357÷10000が実行されました。結果は0です。
プログラム2に戻りました。

商が数字列に変換されました。

結果領域の先頭アドレスに「0」が格納されました。

再びプログラム1、DIVが呼び出されました。
1357÷1000が実行されました。
1357から1000を引いて357、16進数に直すと#0165になりました。

商が1と求まりました。

数字列に変換され主記憶に格納されました。

357÷100が実行されました。
357-100で257、16進数で#0101が求まりました。


257-100で157、16進数で#009Dが求まりました。


157-100で57、16進数で#0039が求まりました。


商が3と求まりました。

主記憶に商の3が格納されました。

57は16進数で#0039です。
57÷10が実行されました。
57-10は47で、16進数では#002Fです。


47-10は37で16進数では#0025です。


37-10は27で16進数では#001Bです。


27-10は17で16進数では#0011です。

17-10は7です。

商が5と求まりました。

主記憶に格納されました。

7÷1が実行され、商の7が求められ、主記憶に格納されました。

出力結果です。

トレースに使ったノートはこちらになります。

;平成23年秋…割り算プログラム2
;呼び出し元のメインプログラム
MAIN START
RPUSH
LD GR1,=#0000 ;割られる数の上位語
LD GR2,=#054D ;その下位語で1357
LAD GR3,KEKKA ;結果領域先頭後
CALL BTOD2 ;プログラム2呼び出し
OUT KEKKA,LEN ;結果格納領域と文字数
RPOP
RET
KEKKA DS 5 ;結果格納領域
LEN DC 5 ;出力処理


;プログラム2
BTOD2
RPUSH
LD GR6,GR3
LAD GR7,4,GR3 ;結果格納領域の末尾アドレス
LAD GR3,UDAT ;除数の初期設定
LP2 CALL DIV ;プログラム1DIV呼び出し
OR GR2,=’0′ ;数字列に変換
ST GR2,0,GR6 ;10進数字1文字格納
CPL GR6,GR7 ;末尾まで処理したか
JZE FIN2
LAD GR6,1,GR6
LD GR1,GR4 ;割られる数の再設定
LD GR2,GR5 ;剰余をGR2へ
LAD GR3,2,GR3 ;割る数を2つ先へ
JUMP LP2
FIN2 RPOP
RET
UDAT DC 0
DC #2710
DC 0
DC #03E8
DC 0
DC #0064
DC 0
DC #000A
DC 0
DC 1

;プログラム1
DIV
PUSH 0,GR6
PUSH 0,GR7
LD GR6,GR1 ;割られる数の上位語
LD GR7,GR2 ;割られる数の下位語
LD GR1,=#FFFF ;商の初期化
LD GR2,=#FFFF
LP LD GR4,GR6 ;割られる数の上位語
LD GR5,GR7 ;割られる数の下位語
ADDL GR2,=1 ;商のカウントアップ
JOV ADJ1 ;桁上り処理へジャンプ
JUMP CONT ;割り算実行
ADJ1 ADDL GR1,=1 ;桁上り処理実行
CONT SUBL GR6,0,GR3 ;引き算しながら割り算していく
JOV FIN
SUBL GR7,1,GR3 ;引き算しながら割り算していく
JOV ADJ2
JUMP LP
ADJ2 SUBL GR6,=1 ;繰り下がり処理
JOV FIN
JUMP LP
FIN POP GR7
POP GR6
RET
END

最後にプログラム3です。
これは10ずつ割って行って工程が多いので、ステップ実行では無く、
一括実行で行います。

このシミュレーターの場合は、実行メニューから一括実行できます。

実行後の主記憶の状態です。


出力結果です。

トレースに使ったノートはこちらになります。

;平成23年秋…割り算プログラム3
;呼び出し元のメインプログラム
MAIN START
RPUSH
LD GR1,=#0000 ;割られる数の上位語
LD GR2,=#054D ;その下位語で1357
LAD GR3,KEKKA ;結果領域先頭後
CALL BTOD3 ;プログラム2呼び出し
OUT KEKKA,LEN ;結果格納領域と文字数
RPOP
RET
KEKKA DS 5 ;結果格納領域
LEN DC 5 ;出力処理

;プログラム3
BTOD3
RPUSH
LAD GR6,4,GR3 ;計算結果末尾のアドレス
LD GR7,GR3 ;計算結果先頭のアドレス
LAD GR3,DAT ;10で割って行く
LP3 CALL DIV ;プログラム1の呼び出し
OR GR5,=’0′ ;余りを数字列に変換
ST GR5,0,GR6 ;数字列を主記憶に格納する
CPL GR6,GR7 ;除算が先頭まで行ったか
JZE FIN3
LAD GR6,-1,GR6 ;除算を1つ前へ
JUMP LP3
FIN3 RPOP
RET
DAT DC 0
DC 10

;プログラム1
DIV
PUSH 0,GR6
PUSH 0,GR7
LD GR6,GR1 ;割られる数の上位語
LD GR7,GR2 ;割られる数の下位語
LD GR1,=#FFFF ;商の初期化
LD GR2,=#FFFF
LP LD GR4,GR6 ;割られる数の上位語
LD GR5,GR7 ;割られる数の下位語
ADDL GR2,=1 ;商のカウントアップ
JOV ADJ1 ;桁上り処理へジャンプ
JUMP CONT ;割り算実行
ADJ1 ADDL GR1,=1 ;桁上り処理実行
CONT SUBL GR6,0,GR3 ;引き算しながら割り算していく
JOV FIN
SUBL GR7,1,GR3 ;引き算しながら割り算していく
JOV ADJ2
JUMP LP
ADJ2 SUBL GR6,=1 ;繰り下がり処理
JOV FIN
JUMP LP
FIN POP GR7
POP GR6
RET
END

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

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

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