AOBA's Information Processing Education
1998/04/05
注意1:このページは、回線を切断した後でゆっくりご覧になってください(テキストを印刷する場合は、その取り扱いに注意してくださるようお願いします)。
注意2:背景が白地の画面を長時間見つめていると頭が痛くなってしまいますので、ここは背景をグレーにしています。
「演習(その1)」
以下のプログラムを実行した場合、行番号06のステップ実行直前(行番号05のステップ実行後)における、ラベルNとラベルMの内容をそれぞれ10進数で答えよ。「プログラム」
01 EX1 START
02 LD GR0,N
03 LD GR1,M
04 ST GR0,M
05 ST GR1,N
06 EXIT
07 N DC 10
08 M DC 20
09 END(注)行番号は解説のために付けたもので、プログラムではありません。
「演習(その2)」
以下のプログラムを実行した場合、行番号09のステップ実行直前(行番号08のステップ実行後)における、ラベルNの内容を10進数で答えよ。
ただし、ラベルNの内容は符号付きの値とみなす。「プログラム」
01 EX2 START
02 LD GR1,HFF00
03 ADD GR1,C15
04 JMI NEXT
05 AND GR1,H00FF
06 JMP LAST
07 NEXT OR GR1,H00F0
08 LAST ST GR1,N
09 EXIT
10 C15 DC 15
11 HFF00 DC #FF00
12 H00FF DC #00FF
13 H00F0 DC #00F0
14 N DS 1
15 END(注)行番号は解説のために付けたもので、プログラムではありません。
「演習(その3)」
1+2+3+......+99+100の値を求め、その結果をNに設定するプログラムを作成する。プログラム中の空欄a〜空欄cを埋めてプログラムを完成させよ。「プログラム」
01 EX3 START
02 (空欄a) ; 0 → GR1
03 L1 ADD GR1,C1 ; GR1+1 → GR1
04 ST GR1,RSV
05 (空欄b) ; 下のステップと合わせて
06 ST GR1,N ; GR1+N → N を行う
07 LD GR1,RSV
08 CPA GR1,C100
09 (空欄c) ; 終わりでなければ分岐
10 EXIT
11 C1 DC 1
12 C100 DC 100
13 N DC 0
14 RSV DS 1
15 END(注)行番号は解説のために付けたもので、プログラムではありません。
演習の解答 「演習(その1)」
解答 Nの内容:20 Mの内容:10行番号2と3でGR0とGR1にそれぞれNとMの内容を入れ、それを行番号4と5でMとNに逆転させて格納しています。
ということで答えは、Nの内容が20でMの内容が10です。「演習(その2)」
解答 −1(16進数で#FFFF)ポイントの一つ目は、行番号03のステップの実行を終了したとき、GR1に設定される値は何かという点です。
行番号03のステップ実行直前のGR1の値は#FF00です。これに15を加算するするのですが、一方が16進数でもう一方が10進数ですので、このどちらかに基数を統一しなければなりません。
#FF00を10進数に変換するのは面倒ですから、15を16進数に変換しましょう。#FF00+15=#FF00+#000F=#FF0F
上記に示すように、行番号03のステップを実行を終了したとき、GR1の内容は#FF0Fになります。
ポイントの二つ目は、行番号04のJMI命令の分岐条件を満たすかどうか、という点です。
結論から言えば、分岐条件を満たします。
なぜなら、行番号04のステップの実行時点におけるGR1の値は(16進数で)#FF0Fであり、これは符号ビット(最も左に位置するビット...第0ビット)が1です。よって負の数ですので、JMI命令の分岐条件を満たしてNEXTへ分岐します。NEXTへ分岐するとGR1の内容(#FF0F)と#00F0の論理和演算(OR)を行いますので、GR1は#FFFFになって、これがNに設定されます。
問題は、ラベルNの内容を符号付きの値とみなし、10進数で回答することを求めていますので、答えは−1です。「#FFFFが−1になることが分からない方のために」
(1)符号ビットが1なので、これは負数と判断する。
(2)負数の場合は2の補数をとる(全ビット反転させて1を加算する)。
#FFFFを全ビット反転すると#0000になり、これに1を加算するのだから、#0001になる(これが#FFFFの2の補数)
(3)#0001は1。したがって、この絶対値を逆転させた−1が#FFFFを10進数に変換した値。「演習(その3)」
解答 空欄a:LD GR1,N
空欄b:ADD GR1,N
空欄c:JMI L1(または JNZ L1)この問題はちょっと難しかったかもしれません。
このような空欄の穴埋め問題を解く場合、最も先に把握しなければならないのは、レジスタや変数(CASLではラベル)の使用目的です。
この問題のGR1は2つの意味を持っています。
一つ目は1〜100(実際は0〜100)まで繰り返すためのループカウンタであり、このカウンタでもって、100までの加算が終了したかどうかを判定しています。
二つ目は途中まで(例えば、50を加算するときは1〜50まで)の累積値です。行番号05でもって、それまでの累積値をGR1に求めてこれをNに格納しています。空欄aについて
GR1はカウンタとして使用します。これは1〜100まで変化すべきものですが、行番号03ですぐに1を加算しますので、GR1の初期値(最初に設定する値)は0にしなければなりません。よって空欄aは、GR1に0を入れる命令が入ります。
プログラムを見ると、行番号13で”N DC 0”のステップがありますのでこれを利用します。
Nの内容をGR1に設定するのですから、”LD GR1,N”とすればよいでしょう。空欄bについて
行番号05と行番号06のステップは深く結びついています。
この部分で、”GR1+N → N”を行いたいのですが(コメント参考)、知っての通り、加算してさらにその結果を任意のラベルの内容(例えばNの内容)に格納する命令がCASLにはありません(ADD命令の加算結果はレジスタです)。
ということで、一旦、加算結果をGR1に設定し、それをNに格納する処理を行う必要があります。つまり、”GR1+N → N”を行うために、05 ADD GR1,N ; GR1+N → GR1
06 ST GR1,N ; GR1 → Nと、2段階に分けているのです。
なお、行番号05を実行すると、ループカウンタとして使用しているGR1の内容が破壊されますので、行番号04で待避して行番号07で復元しています。空欄cについて
ここは簡単だったでしょう。
GR1が100かどうかを判定して、100未満ならば引き続き加算処理を行えばよいのですから、”JMI L1”が求める答えです(”JNZ L1”でもよい)。ということで、また来週。