x86 CPUの電源投入後の動作モードであるリアルモード(16ビットモード)向けに、アセンブラでズンドコきよしのプログラムを書いてみました。
OSレスで動作するように作っていますので、生成されるイメージzundoko.img
は以下のようにQEMUで実行できます。
$ qemu-system-i386 -fda zundoko.img
- GCC
- Make
- QEMU(qemu-system-i386)
Makefileを用意していますので、make run
でビルドと動作確認を行えます。
C言語で同等の実装を行ったものをzundoko_algo.c
という名前でこのリポジトリに入れています。
ズンドコきよしの解き方としては、以下のように考えました。
- zunカウンタゼロクリア
- 乱数生成(0か1)
- ループ
- 乱数 == 1
- print "zun"
- zunカウンタインクリメント
- 乱数 == 0
- print "doko"
- zunカウンタ < 4
- zunカウンタゼロクリア
- zunカウンタ >= 4
- ループ脱出
- 乱数 == 1
- print "kiyoshi"
乱数の種のためのタイマーカウンタ値取得と、画面への文字出力は、BIOSの機能を呼び出すことで実現しています。(BIOS割り込みルーチン)
また、乱数を生成する機能はBIOSに無いので、線形合同法という方法で実装しました。
ズンドコきよしと乱数生成のアルゴリズムは共に、「記憶しておかなければならないデータ」が少ないアルゴリズムです。
- ズンドコきよし -- zunカウンタのみ
- 乱数生成(線形合同法) -- 漸化式の演算結果(Xn)のみ
そこで、すべてのデータをレジスタで管理し、メモリへのread/writeを行わないように作ってみました。(ただし、CPUが実行する命令をメモリから取り出す(フェッチ)ためのreadは例外。命令フェッチのためのread以外にメモリアクセスは発生しないように作ってみました。)
zundoko.S
で使用するレジスタは以下のとおりです。
レジスタ名 | 用途 |
---|---|
ax,bx,cx,dx | 演算のための値格納、BIOS割り込みルーチンへの値受け渡し |
di | zunカウンタ |
si | 漸化式の演算結果(Xn) |