この記事では、アセンブラ言語で簡単なループとインクリメントをして、番長皿屋敷のお皿の枚数を数える例題を掲載しております。
怪談話で有名な、「1ま〜い」、「2ま〜い」・・・と数えていくのは、プログラミングの基礎トレーニングになると思います。
世間では「地球沸騰化」、なんて言っていますね。
多分2023年のトレンドになるのではないでしょうか。
毎日暑いので、アセンブラの勉強では涼しくなりたいです。
そこで、怪談話を題材に、プログラミングをしてみようと思いつきました。
個人的には「番町皿屋敷」は、プログラミングの中でもループの勉強になると思います。
1ま~~~い、
2ま~~~い、
そう、ループとインクリメントです!
アセンブラCASL2を使って基本情報技術者試験対策も兼ねて
下記の結果になるプログラミングをしてみました。
LADとLDの違いについては、こちらの外部記事が分かりやすいです。
TEST START
RPUSH
LAD GR1,1;GR1に1を設定
;<< ここからループ >>
LOOP LD GR2,GR1;GR2にGR1の数を読み込む
ADDL GR2,='0';GR2の値に文字コード「'0'」を加算
ST GR2,SARA;GR2の値をSARAに格納
OUT SARA,LEN;皿の枚数を出力
LAD GR1,1,GR1;GR1をインクリメント
CPL GR1,=10;GR1が10まで達したのか比較(ループを続けるか否かの判断)
JMI LOOP;GR1が10未満であれば、ループは続行
OUT MOJI,LEN2;「サラ割れた」のメッセージ出力
RPOP
RET
SARA DS 1;皿に文字数1枠を確保する
TANI DC 'MA-I';皿の単位の数え方は「枚(まーい)」
LEN DC 5;1枚は「1MA-I」と5文字で表示
MOJI DC 'SARA WARETA!';「皿割れた」の文字列
LEN2 DC 12;上記の皿の文字列の字数
END
それでは、このサブルーチンを実行していきます。
まず、GR1に1を設定します。
GR1はループカウンタ用に使って、GR2は皿の枚数の出力用に使うので、GR1の値をGR2に写します。
GR2にGR1の値を読み込みます。
GR2の値を使って、「1まーい」と出力したいのですが、そのためには文字コードの理解が必要になります。
紛らわしいのですが、「’1’」の文字コードは「0001」ではなく、「0031」です。
つまり、OUT命令で「1」と出力したいのであれば、文字コードを踏まえて「+30」してから出力します。
そこで、ADDL命令でGR2に「’0’」を足しておりますが、CASL2での「’0’」の文字コードは「0030」です。
この辺りの説明が分かりにくい際には、CASL2の文字コードについてこちらの外部記事が分かりやすいです。
ST命令で文字列SARAにGR2の「+30」をした値を格納してOUT命令で右側のコンソールに出力しています。
STの文字数は1文字、単位の「MA-I」は4文字なので、LENには合わせて5文字分出力出来るように5と設定しています。
現在GR1は1枚なので、LADを使ってインクリメントして、GR1の値を「2」にします。
その、インクリメントの仕組みなのですが、
LAD GR1,1,GR1
で、GR1に「GR1の値+1番地」の値アドレス値を送ることによって、GR1自身に、1加算のインクリメントをしています。
この仕組みについては、先ほどのLDとLADの違いの外部記事が参考になり、ロードアドレス命令を用いた加算については、こちらの外部記事に掲載されています。
ちょっと面倒だな〜〜と思われた方は、ループでのインクリメントのテクニックなんだな、程度に軽く流してもらっても大丈夫です。
インクリメントによって、GR1の値は1から2に1つ増えました。
CPLで「10」と比較して、10よりも小さかったらJMIでLOOPに戻ります。
現在GR1の値は「2」であり、2は10より小さいので、フラグのSFがマイナスとなり、LOOPに戻ります。
このSFがマイナスになった仕組みですが、アセンブラでは比較の時に減算が行われます。
CPL GR1,=10;GR1が10まで達したのか比較(ループを続けるか否かの判断)
ここで、GR1が2なので、10と比較するために「2-10=マイナスの値」と計算されて、SFフラグがマイナスなので「1」になったという仕組みです。
それで、JMIでマイナスになったのでLOOPまで戻って、このループをGR1の値が10未満の間は繰り返されます。
・
・
・
あとは繰り返しなので、「9まーい」が出力される所まで進めます。
現在、「8まーい」まで出力されていて、コンソールの表示はこのようになっています。
レジスタの値は、このようになっています。
GR1が「9」なので、10未満の為SFフラグが1であり、LOOPまで戻ってきました。
GR2にGR1の値が読み込まれます。
GR2に「’0’」を加算することによって、文字コードが30足されます。
「0009」から「0039」になって、文字「9」が出力出来るようになりました。
ST命令で、文字「9」をSARAに格納します。
OUT命令でコンソールに「9まーい」が出力されました。
LAD命令でGR1がインクリメントされて、「9」から「A」になりました。
16進数では、Aは10です。
16進数が苦手な方は、こちらの外部記事が分かりやすいです。
CPLで10になったGR1と10が比較され、ここでも減算が用いられ、GR1-10=0なので、ゼロフラグが立って1になりました。
なので、JMIによる分岐は行われずにループを抜けました。
ループを抜けた所で、「皿割れた」のメッセージが出力されます。
最後の「SARA WARETA!」ですが、
これは、そのお皿が ”さらわれた”と、皿が割れたのダジャレです。
ちょっと怖かったですか(笑)
これで少しでも体感温度下がりましたら夏を乗り切れそうです。
お疲れ様でした。
ここで一旦、写真で休憩を挟みます。
千葉県の房総半島の外房、御宿の海です。
ここから、復習&アウトプットタイムです!!
下記のコードをシミュレーターにコピペして、コメントを頼りに先ほどのコードを覚えているか入力して見て下さい。
上手く動いたら、値などを好きなように変えて動かして見て下さい。
この復習は学習直後は勿論、明日など少し日を開けて行うと、更に効果的です!!
TEST START
RPUSH
;GR1に1を設定
;<< ここからループ >>
;GR2にGR1の数を読み込む
;GR2の値に文字コード「'0'」を加算
;GR2の値をSARAに格納
;皿の枚数を出力
;GR1をインクリメント
;GR1が10まで達したのか比較(ループを続けるか否かの判断)
;GR1が10未満であれば、ループは続行
;「サラ割れた」のメッセージ出力
RPOP
RET
SARA DS 1;皿に文字数1枠を確保する
TANI DC 'MA-I';皿の単位の数え方は「枚(まーい)」
LEN DC 5;1枚は「1MA-I」と5文字で表示
MOJI DC 'SARA WARETA!';「皿割れた」の文字列
LEN2 DC 12;上記の皿の文字列の字数
END
皆さま、大変お疲れ様でした。
この記事最後のブレイクタイムPhotoは・・・
江ノ島の岩場です。
片瀬江ノ島駅から徒歩数分のところで船に乗れましたので、岩場まで行って来ました。
仕事や勉強のリフレッシュに、趣味で写真を撮っておりますので、宜しかったら フォトストック写真ACさん の投稿もご覧頂けますと、大変嬉しい限りでございます!!
こちら、無料の「ダウンロードユーザー」に登録して頂けると、無料で写真のダウンロードが可能になります。
※ 先にGoogleアカウントを作成して頂くと、登録が ラク です♪
最後までご精読、誠にありがとうございました!!
自己紹介
アセンブラ自作サンプルとFE出題範囲のアリゴリズムへ
アセンブラ過去問プログラムへ
プログラミング未経験者はアセンブラと表計算どっち!?
基本情報技術者試験トップへ
午前免除試験
午後試験のオススメ本
スコアレポート