はじめに
皆さまはVB.NETにどのようなイメージをお持ちでしょうか? 筆者がよく聞くイメージは「初心者用」です。開発元のマイクロソフト社のWebページにも「Visual Basic 2008 Express EditionはWindowsアプリケーションの楽しく簡単な作成方法に興味を持つ、趣味で開発を行うユーザー、プログラミング初心者、および学生に最適な開発ツールです」と書いてありますので、そのイメージはあながち間違いではないでしょう。
おそらくそれが原因なのでしょうが、VB.NETであまりディープな内容にチャレンジしている人を筆者は見かけません。デバッガ実装、OS開発、RDBMS実装、機械語解析などのディープな内容は大半C言語で行われております。C言語を選択するのは実用的な観点から言えば正解なのですが、だからといってディープな内容が楽しめる言語はC言語だけではありません。さすがにOS開発は無理なのですが、実のところ0と1さえ操作できればいいので一般的なバイナリプログラミングはVB.NETで十分に楽しめます。
本記事はVB.NETの初歩的な記法だけを使って、簡単な機械語で動く仮想CPUの実装法を解説します(※CPUにもいろいろありますが、この記事ではIntel社が製造しているCPUを対象とします)。
その過程を通じて、初心者でもバイナリプログラミングが楽しめることと、バイナリプログラミングの魅力を伝えたいと思っております。
対象読者
この記事はVB.NETの基礎的な構文が書ける人を対象にしています。
必要な環境
VB.NETであれば、どのバージョンでもOKです。
事前準備
まずはVB.NETを準備しましょう。VB.NETはマイクロソフト社のWebページから無料で入手できます。インストール方法は同じページの「はじめての方のためのインストール方法」で詳しく説明されていますので、ぜひ一度目を通してください。
次に必要なのはCPUの仕様書です。これはインテル社のWebページにあります。このページには膨大な資料があり圧倒されると思いますが、今回使用するのは「IA-32 インテル アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、上巻: 基本アーキテクチャー」(以下、マニュアル上と表記) と「IA-32 インテル アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 B: 命令セット・リファレンス N-Z」(以下、マニュアル中Aと表記)、「IA-32 インテル アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 B: 命令セット・リファレンス N-Z」(以下、マニュアル中Bと表記)です。いつでも読めるように、あらかじめダウンロードしてください(PDF形式)。
コンピューターの基礎とCPU
仮想CPUを作るには、まずコンピューターとCPUの基礎を軽く学ばなければなりません。少し退屈かもしれませんが、なるべく簡潔に説明しますので最後まで読んでください。
プログラミングをする際、多くの人はコンピューターが0と1の処理で動いていると聞いていると思いますが、ほとんどの人がそれを実感できないでいます。もちろん筆者もそうでした。その原因はVB.NETが高度に抽象化されたプログラミング言語だからです。プログラミング言語レベルで高度に抽象化していると、コンピューターとの細かいやり取りを気にする必要がなく、生産性は高くなりますが、それゆえに0と1で動いている実感が得られません。また、0と1で動いているとは何を意味しているのでしょうか?
それは、コンピューターを制御しているCPU(Control Processor Unit)が0と1しか理解できないことを指しています。実際に見たことはないのですが、昔は10進数(0~9)で動くCPUなどもあったそうです。ですが、電気を扱う際にはプラス(1)とマイナス(0)で動作する方が効率がよいので、現在の0と1の2進数を解釈するCPUが生き残っているようです。ですから、コンピューターを知るにはCPUを知ることが重要なのです。
数の表現法
先ほど、CPUが0と1しか理解しないことを説明しました。この数値表記を2進数と呼びます。2進数では、位の数が2になると1桁繰上がります。一方、我々が普段使用している1桁が0~9の表記方法は10進数と呼びます。他にも8で1桁繰り上がる8進数、16で1桁繰り上がる16進数と呼ばれる数値の表現法があります。これらの数値の表現は互いに変換可能です。
例えば11をそれぞれの数値表記で表すと、次のようになります。
1011 ( 8 + 2 + 1)
13 ( 8 + 3 )
11
B ( 10~15はA~Fで表します )
現時点ではよく分からないかもしれませんが、細かい計算法については仮想CPUを実装する際に改めて説明します。