本当に初心者の人に捧げるコンピューター入門


ソフトウェア プログラム編その4

機械語で迷宮から・・・

 この章では迷宮脱出のアルゴリズムを前章で説明した偽機械語で書いてみました。しかし本物の迷宮よりよっぽど迷宮のようです・・・筆者もやらなきゃよかったと深く後悔しています・・・
 ですから皆さんの場合はこんな物をあまり深く理解する必要はありません。とにかく機械語というのはこんな感じの物だということさえ分かっていただければ結構ですので、ざっと流し読みしてもらえばいいです。


迷宮脱出プログラム:機械語版




データの初期化
1000  LD  230  211    最初はスタート地点(211番地)にいるので
              230番地に211と書き込む
1003  LD  231  90     最初は東(90度)の方向を向いているので
              231番地に90と書き込む

ループの開始
1006  CMP  230  13     現在地が終点かどうか調べる。13番地にいた
              ら終点。
1009  JZ  1351          終点だったらプログラム終了地点にジャンプ。

現在地の周りに道がいくつあるか数える
1011  LD  250  0      250番地(計算のため一時的に使用)に0をセ
              ットする。

1014  LD  260  [230]   260番地(計算のため一時的に使用)に現在位
              置をセットする。
1017  SUB  260  15     北の方向に隣接した位置を求める
1020  CMP [260]  1      隣接位置が壁かどうか調べる
1023  JZ  1028         (壁だった場合東方向のチェックに移る)
1025  ADD  250  1      壁でなければ250番地の内容に1を足す

1028  LD  260  [230]   同様に東方向が壁かどうか調べる
1031  ADD  260  1
1034  CMP [260]  1
1037  JZ  1042
1039  ADD  250  1

1042  LD  260  [230]   同様に南方向が壁かどうか調べる
1045  ADD  260  15
1048  CMP [260]  1
1051  JZ  1056
1053  ADD  250  1

1056  LD  260  [230]  同様に西方向が壁かどうか調べる
1059  SUB  260  1
1062  CMP [260]  1
1065  JZ  1070
1067  ADD  250  1

1070  CMP  250  4      数えた結果、道が4カ所の場合は、
1073  JZ  1087         「分かれ道の場合」にジャンプ

1075  CMP  250  3      数えた結果、道が3カ所の場合は、
1078  JZ  1087          同様に「分かれ道の場合」にジャンプ

1080  CMP  250  2      数えた結果、道が2カ所の場合は、
1083  JZ  1201         「普通の道の場合」にジャンプ

1085  JP  1297          それ以外の場合は道は1カ所しかないはずなの
              で「行き止まりの場合」にジャンプ

現在地が分かれ道の場合

左がどちらかを調べる
1087  LD  260  [231]   260番地(計算のため一時的に使用)に現在の
              向きをセットする。
1090  ADD  260  270   260番地に270を足して
1093  CMP  260  360   360より大きいかチェックする
1096  JS  1100      260番地の中身が360より大きければ
              1100番地に飛ぶ
1098  JP  1103      1103番地に飛ぶ
1100  SUB  260  360   360より大きかった場合は360を引く
               (ここまで来れば260番地に左方向の方角が
              セットされている)

1103  LD  261  [230]   261番地(「左に隣接している場所」のため一時
              的に使用)に現在地をセットする
1106  CMP  260  0   左が北であるかチェックする
1109  JNZ  1116     北でなければ次)
1111  SUB  261  15   261番地を北に隣接した位置にする
1114  JP  1141     「左に道があった場合」にジャンプ

1116  CMP  260  90   左側が90度の場合 以下同文。
1119  JNZ  1126
1121  ADD  261  1
1124  JP  1141

1126  CMP  260  180  左側が180度の場合 以下同文。
1129  JNZ  1136
1131  ADD  261  15
1134  JP  1141

1136  SUB  261  1   後は西しか残らないので
1139  JP  1141

左に道があった場合、左に進む

1141  CMP [261]  0   左に隣接している場所が道だった場合は
1144  JNZ  1154     (違った場合は次)
1146  LD  231  [260]  左を向いて
1149  LD  230  [261]  左に行く
1152  JP  1006     「ループ開始地点」に戻る

左に道がなかった場合、まっすぐ進む

1154  CMP  231  0    現在の向きが北かどうかチェック
1157  JNZ  1167     (北でなければ次)
1159  LD  231  0    北を向いて
1162  SUB  230  15   北に行く
1165  JP  1006     「ループ開始地点」に戻る

1167  CMP  231  90   現在の向きが東かどうかチェック…以下同文
1170  JNZ  1180
1172  LD  231  90
1175  ADD  230  1
1178  JP  1006

1180  CMP  231  180   現在の向きが南かどうかチェック…以下同文
1183  JNZ  1193
1185  LD  231  0
1188  ADD  230  15
1191  JP  1006

1193  LD  231  270   残りは西と決まっているので西を向いて
1196  SUB  230  1    西に行く
1199  JP  1006

現在地が普通の道の場合は、道なりに進む


まず後ろ側の方向を調べる

1201  LD  260 [231]    現在の向きを260番地(後ろの方向を調べる
              ために一時的に使用)にセット
1204  ADD  260  180   260番地の内容に180を足して
1207  CMP  260  360   360を越えていたら
1210  JS  1214
1212  JP  1217
1214  SUB  260  360   360を引く

後ろでない方向に存在する道に向かって進む

1217  LD  261  230     261番地(隣接位置を調べるため一時的に使
              用)に現在位置をストア
1220  SUB  261  15   261番地の中身を北に隣接した位置にする
1223  CMP [261]  0    そこが道かどうか調べる
1226  JNZ  1241     (道でなければ次)
1228  CMP  260  0    北が後ろ側かどうか調べる
1231  JZ  1241     (後ろだったら次)
1233  LD  231  0    北に向く
1236  SUB  230  15   北に進む
1239  JP  1006     「ループ開始地点」に戻る

1241  LD  261  230   261番地に現在位置をストア
1244  ADD  261  1    東に隣接した位置を求める
1247  CMP [261] 0    そこが道かどうか調べる
1250  JNZ  1265     (道でなければ次)
1252  CMP  260  90   道の場合後ろの方向を調べる
1255  JZ  1265     後ろだったら次
1257  LD  231  90   東を向く
1260  ADD  230  1    東に進む
1263  JP  1006

1265  LD  261  230   261番地に現在位置をストア
1268  ADD  261  15   南に隣接した位置を求める
1271  CMP [261] 0    そこが道かどうか調べる
1274  JNZ  1289     道でなければ次
1276  CMP  260  180   方向を調べる
1279  JZ  1289     後ろだったら次
1281  LD  231  180   南を向く
1284  ADD  230  15   南に進む
1287  JP  1006

1289  LD  231  270   西を向く
1292  SUB  230  1    西に進む
1295  JP  1006

現在地が行き止まりの場合は引き返す

後ろ側の方向を調べる

1297  LD  260 [231]
1300  ADD  260  180
1303  CMP  260  360
1306  JS  1310
1308  JP  1313
1310  SUB  260  360   260番地に後ろ側の方向が入る

後ろに向き直って前に進む

1313  LD  231 [260]   現在の向きを後ろ向きに変える

1316  CMP  260  0   「後ろ向き」が北かどうかチェック
1319  JNZ  1326     (北でなければ次)
1321  SUB  230  15   北に一歩進む
1324  JP  1006     「ループ開始地点」に戻る

1326  CMP  260  90   「後ろ向き」が東かどうかチェック…
1329  JNZ  1336
1331  ADD  230  1
1334  JP  1006

1336  CMP  260  180  「後ろ向き」が南かどうかチェック…
1339  JNZ  1346
1341  ADD  230  15
1344  JP  1006

1346  SUB  230  1    残りは西なので…
1349  JP  1006

プログラムの終了
1351  HALT
 やっとできました!あとはこれを機械語に翻訳すればやっとコンピューター上で動くようになりますが・・・もう疲れたのでその作業はやめます。暇な人は前章の表に従ってこれを機械語の数字列に変換してみてください。
 それにしても、いくらコンピューターの計算速度が速くとも、これを作っている間にあなたはモンスターの餌食になってしまうでしょう。


とにかく本気で疲れた・・・



 ここまで読んでいただいて(本気で読んだ人などいないでしょうが・・・)なんだか気が遠くなってきたあなたは正常です。プログラマーってこんな物を毎日書いているのか、プログラマーってすごいなあ、と思ったあなたも正常です。

 しかしプログラマーといえども、実はあなたとそう違いはないただの人間なのです(何が違うかと言えば、コンピューターが本気で好きかどうかというところでしょうか?)ですからプログラマーでもこんな物を書くのはひどく疲れる作業なのです。

 そこでもう少しわかりやすく楽にプログラムが書けないものか、とみんな考えます。その結果できあがったのが高級言語という物です。
 次章以降ではそれについて概説してみましょう。

 暇な人はこちらの本物の機械語の説明も読んでみてください。


目次へ 目次へ 次へ