矢沢 久雄

●マシン語=数値で表されたプログラム

 皆さんは,アルゴリズム,データ構造,構造化,オブジェクト指向といった言葉を聞いたことがあるでしょうか。これらの言葉を聞いて,プログラムを難しいものと思ってしまう人もいるかもしれません。しかしコンピュータは,入力,演算,出力しかできず,すべての情報を数値で取り扱うことしかできないのです。そんな単純なコンピュータを動作させるプログラムが,そんなに難しいはずなどありません。今回は,プログラムの本当の姿がどうなっているかを見てみましょう。

図1●プログラムの中身は、数値の羅列だ
 Windowsをお使いなら,プログラムは,拡張子が.exeまたは.dllとなったファイルとしてハード・ディスクに記録されています。ここでは,筆者オリジナルのダンプ・プログラムを使って,MyProg.exe(これも筆者が作ったオリジナルのプログラムです)の中身を調べてみると,図1[拡大表示]のようになっていることがわかりました。

 意味不明な2けたの16進数の数値が羅列されていますね。これがプログラムの正体であり,「マシン語」または「ネイティブ・コード」と呼ばれます。実際には,個々の16進数が8ビットの2進数(2けたの16進数=8ビットの2進数)としてメモリーにロードされ(ディスクからメモリーにコピーされ),それをプロセサが解釈することで,プログラムが動作します。個々の数値は,プロセサに与える命令,または命令の対象となるデータのいずれかを表しています。すなわち符号化された命令またはデータの集合体が,プログラムの正体なのです。

 図1に示された数値のうち,どれかを指さしてください。その数値は,命令またはデータのいずれかです。プログラムとは,命令またはデータを表す数値の羅列にすぎないのです。アルゴリズムも,データ構造も,構造化も,オブジェクト指向も,マシン語の中には見えません。コンピュータとは,実にシンプルなものです。

●アセンブラ

 大昔のプログラマは,マシン語を使ってプログラミングしていました。コンピュータにはキーボードなどありませんでしたから,ON/OFFのスイッチを使って2進数でプログラムを入力していたのです。それではあまりにも面倒なので,マシン語の個々の数値が表す命令に,英単語を短くしたようなニックネーム(ニーモニックと呼ばれます)を付け,それらを書き並べてプログラミングする方法が考案されました。これを「アセンブリ言語」と呼びます。

 アセンブリ言語で記述されたプログラムは,マシン語に変換されてから実行されます。この変換作業を行ってくれるプログラムも開発され「アセンブラ」と呼ばれました。アセンブラが開発されるまでは,アセンブリ言語からマシン語への変換を手作業で行いました。これを「ハンド・アセンブル」と呼んでいたことも覚えておいてください。

 リスト1は,アセンブリ言語で記述されたプログラムの例です。mov(moveの略=データをコピーせよ)やadd(addtionの略=加算せよ)などがニーモニックです。アセンブリ言語の文法は,実に単純です。「動詞+目的語」という構文しかありません。これは,英語の命令文と同じ構文です。動詞の部分は「○○せよ」という命令で,目的語の部分は「△△を」というように命令の対象となるデータ(レジスタの名前,メモリのアドレス,I/Oのアドレスなど)を指定します。目的語は,1つの場合も複数の場合もあります。目的語が複数の場合は,カンマで区切ります。ret(戻れ)のように,目的語のない命令もあります。リスト1のプログラムをマシン語に変換すると,図1のような数値の羅列になるわけです。

リスト1●アセンブリ言語で記述されたプログラムの例

(動詞)	(目的語)
mov     dword ptr [ebp - 4],1
mov     dword ptr [ebp - 8],2
mov     eax,dword ptr [ebp - 4]
add     eax,dword ptr [ebp - 8]
mov     dword ptr [ebp - 0Ch],eax
mov     ecx,dword ptr [ebp - 0Ch]
push    ecx
push    offset string "%d\n"
call    printf (00401080)
add     esp,8

 アセンブリ言語でプログラムを作成する作業は,コンピュータの動作,すなわちプロセサが行う入力,演算,出力をそのまま記述するものとなります。「動詞+目的語」という命令文の構文しかないということは,プログラムとはプロセサに対する命令を順番に書き並べたものだと言えます。「△△を○○せよ」,「△△を○○せよ」,「△△を○○せよ」…の繰り返しです。実にシンプルなものです。

●高水準言語

 家電などに組み込まれているマイコンを制御するプログラムを作成する場合には,今でもアセンブリ言語を使うことがあります。ただし,Windowsで動作するワープロやゲームなどのアプリケーション(プログラムの種類に関しては,連載の第5回で説明します)を作成する場合には,アセンブリ言語を使う人はほとんどいません。なぜなら,プログラムの規模が大きいため,アセンブリ言語でプロセサの動作を細かく記述するのでは,あまりにも面倒だからです。

 アプリケーションの開発には,より人間の言葉(英語)に近い表現でプログラミングできる「高水準言語(高級言語とも呼ばれる)」が使われます。高水準言語に対して,マシン語とアセンブリ言語のことを「低水準言語」と呼びます。低水準とは,機能が低いという意味ではなく,コンピュータのハードウエアに密接したプログラムを記述するという意味です。

 高水準言語には,COBOL,FORTRAN,BASIC,C言語,Pascal,C++,Java,C#など様々な種類があります。高水準言語の種類の違いは,英語の方言のようなものであり,方言の違いによってプログラミングしやすい分野があります。例えば,COBOLなら金銭計算プログラム,FORTRANなら科学技術計算プログラム,C言語なら構造化プログラミング(プログラムの流れを構造化すること),C++,Java,C#ならにオブジェクト指向プログラミング(プログラムをオブジェクトの集合体とすること)に適している,といった具合です。

 リスト1に示したアセンブリ言語のプログラムをC言語という高水準言語で記述すると,リスト2のようになります。これは,1+2の加算結果を画面に表示するものです。高水準言語で記述されたプログラムは,コンパイラと呼ばれる変換プログラムによってマシン語に変換されてから実行されます。高水準言語で記述された1行のプログラムが,複数行のマシン語になります。すなわち,リスト2で使われているprintfのような高水準言語の命令は,複数のマシン語命令に変換されるのです。

リスト2●C言語で記述されたプログラムの例

#include 
int main(int argc,char* argv[])
{
    a = 1;
    b = 2;
    c = a + b;
    printf("%d\n",c);
    return 0;
}

 高水準言語が考案されたことで,コンピュータのハードウエアに関する知識が乏しい人でもプログラミングができるようになりました。ただし,この連載で取り上げているようなハードウエアやアセンブリ言語の知識を持っているどうかで,できあがるプログラムの品質に違いが出てきます。コンピュータの仕組みを知っていれば,よりよい(実行速度が速く,サイズの小さい)プログラムを作成できます。自分で作成したプログラムが実行される様子をイメージできるため,ますますコンピュータが楽しいものとなります。かく言う筆者も,わかって楽しいからこそ,コンピュータを続けていられるのです。