当サイトの一部ページには、アフィリエイト・アドセンス・アソシエイト・プロモーション広告を掲載しています。

Amazonのアソシエイトとして、Security Akademeiaは適格販売により収入を得ています。

広告配信等の詳細については、プライバシーポリシーページに掲載しています。

消費者庁が、2023年10月1日から施行する景品表示法の規制対象(通称:ステマ規制)にならないよう、配慮して記事を作成しています。もし問題のある表現がありましたら、問い合わせページよりご連絡ください。

参考:令和5年10月1日からステルスマーケティングは景品表示法違反となります。 | 消費者庁

Assembler program【NandGame編】

2023年11月13日

はじめに

いつもブログをご覧いただきありがとうございます。

FIRE生活中のIPUSIRONです😀

IPUSIRONのプロフィールを見る

Assembler programレベル

Assembler programレベルのゴールは、コンピュータの緑ランプを少なくとも3回点滅させるプログラムをアセンブリー言語で書くことです。

外部デバイスであるランプはアドレス7FFFhにメモリーマップされています。このアドレスの16ビットのうち、0ビット目と1ビット目がランプに接続されています。それぞれOn端子、Off端子につながっています。

※ランプを含む外部デバイスが影響を受けるのは、ビットが0から1に変わるときだけです。

そしてビット0と1にメモリーマップされています。

ビットを1にする

0 ランプが点灯
1 ランプが消灯

外部デバイスが影響を受けるのは、ビットが0から1に変わるときだけです。

アセンブリー言語の仕様

本CPUにおけるアセンブリー言語の仕様

[Show Assembler Help]ボタンを押すと右側にアセンブリー言語の各命令が表示されます。

Assembler programレベルを解く

ランプを「点灯⇒消灯⇒点灯⇒・・・」としたければ、「0ビット目をON⇒1ビット目をON⇒・・・」とすればよいのです。やり方はいろいろありますが、アドレス7FFFhのメモリー値を0からインクリメントしていくのがもっとも簡単な方法です。

インクリメントということは「0000 0000 0000 0000b⇒0000 0000 0000 0001b⇒0000 0000 0000 0010b⇒・・・」となります。これは先ほどの流れである「0ビット目をON⇒1ビット目をON⇒・・・」を満たしています。

ただし、「0000 0000 0000 0010b⇒0000 0000 0000 0011b」では消灯したままです。ランプの仕様的にOff端子が優先されてしまうためです。

そこで、0000 0000 0000 0000bにするリセット処理が必要になります。

以上を踏まえてプログラムを実装すると次のようになります。

# Assembler code 
A = 0x7FFF
# 1回目の「(消灯⇒)点灯⇒消灯」
*A = *A + 1
*A = *A + 1
# 初期状態にリセット.
*A = 0

# 2回目の「点灯⇒消灯」
*A = *A + 1
*A = *A + 1
*A = 0

# 3回目の「点灯⇒消灯」
*A = *A + 1
*A = *A + 1
*A = 0

computerの[Tick]ボタンや[Reset]ボタンを押して、1命令ずつ実行して、内部状態の変化を確認してください。

最終手金[Check solution]ボタンを押すと、レベルクリアとなります。

共通処理をまとめる【別解】

先ほどの解答には冗長なコードがあります。「点灯⇒消灯」の処理を共通化し、ループで繰り返せばよいだけです。

ゴールの条件は3回以上なので、無限ループでもクリアになるわけです。

プログラムのアドレスを直接数値で指定してもよいですが、アセンブリー言語の仕様を見るとラベルという概念があります。これを使うと、アドレス値を意識する必要はありません。

以上を踏まえてプログラムを実装すると次のようになります。

# Assembler code 
LOOP:
A = 0x7FFF
# 「(消灯⇒)点灯⇒消灯」
*A = *A + 1
*A = *A + 1
# 初期状態にリセット.
*A = 0
A = LOOP
JMP

コード量が減ってすっきりしました。