はじめに
本記事はVB.NETの初歩的な記法だけを使って、簡単な機械語で動く仮想CPUの実装法を解説します(※CPUにもいろいろありますが、この記事ではIntel社が製造しているCPUを対象とします)。その過程を通じて、初心者でもバイナリプログラミングが楽しめることと、バイナリプログラミングの魅力を伝えたいと思っています。
今回は第12回で課題とした機械語駆動式関数電卓の実装例を紹介します。これはあくまでも実装例であって、自分が実装したものとこの解説で違うところがあっても、第12回で提示した設計の方針さえ合っていればいいので気にしないでください。
下準備
今回は前回の実装を拡張していきますので、あらかじめ第13回までの部分の実装を済ませておいてください。
仕様9の実装
読みやすいように要求仕様9を再掲します。
「機械語の実行を柔軟に行いたいので、逐次実行・範囲実行・一括実行ができるようにする」
この仕様については既に逐次実行ができる状態なので、範囲実行と一括実行について考えることから始めます。
範囲実行とは、このアプリケーションでは選択した機械語を実行することです。より具体的に言うと、CommandListのSelectedItems
プロパティの値である各Command
オブジェクトを使用してIntelCpu
オブジェクトを実行することです。
一方、一括実行は簡単で、CommandListのItemsを使用して今まで指定されたすべての命令を実行するだけです。
次に考えるべきことは「どのタイミングで実行するか」です。このアプリケーションでは、EnterButton
オブジェクトのClickイベントで行います。
ここまで考えが纏まったら後はコーディングするだけです。筆者の実装例を掲載した後、説明します。
'範囲実行もしくはすべて実行を行います Private Sub EnterButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EnterButton.Click 'エラー判定 If Me.CommandList.Items.Count = 0 Then MessageBox.Show("1つ以上の命令を指定した後、Enterキーを押してください。", "操作エラー", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If If Me.RegionMenu.Checked = True Then '範囲実行 'エラー判定 If Me.CommandList.SelectedItems.Count = 0 Then MessageBox.Show("実行する命令を必ず1つ以上選択してください", "操作エラー", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If '実行する命令を読み込む '発行した命令も記録しておく For i As Integer = 0 To Me.CommandList.SelectedItems.Count - 1 Dim cmd As Command = Me.CommandList.SelectedItems(i) Me.cpu.ReadBinary(cmd.ToBinary()) Me.CommandList.Items.Add(cmd) Next '命令の解析と実行を行う Me.cpu.AnalyzeBinary() Me.cpu.ExecuteCommand() ElseIf Me.AllExeMenu.Checked = True Then 'すべて実行 Me.InitRegisters() 'まずは初期化 '実行する命令を読み込む '発行した命令も記録しておく For Each cmd As Command In Me.CommandList.Items Me.cpu.ReadBinary(cmd.ToBinary()) Next '命令の解析と実行を行う Me.cpu.AnalyzeBinary() Me.cpu.ExecuteCommand() End If End Sub
この実装の大まかな流れは、エラーチェックの後、該当するCommandの読み込みを行い、最後に解析を実行しています。Command
クラスとIntelCpu
クラスの実装を工夫したおかげでこの実装は非常に簡単です。後は実行関係のメニューのコーディングをするだけです。
#Region "実行メニュー関連" '実行モードを切り替えます Private Sub StepExeMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StepExeMenu.Click If Me.StepExeMenu.Checked = True Then Me.RegionMenu.Checked = False Me.AllExeMenu.Checked = False End If End Sub '実行モードを切り替えます Private Sub RegionMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RegionMenu.Click If Me.RegionMenu.Checked = True Then Me.StepExeMenu.Checked = False Me.AllExeMenu.Checked = False End If End Sub '実行モードを切り替えます Private Sub AllExeMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AllExeMenu.Click If Me.AllExeMenu.Checked = True Then Me.StepExeMenu.Checked = False Me.RegionMenu.Checked = False End If End Sub #End Region
実質的な処理は先ほどコーディングしたEnterButtonのClickイベントにありますので、各メニューではチェックの切り替えを行っているだけです。以上で仕様9の実装は終わりです。次は10と11の実装を行います。