← Prev (00)

(02) Next →

From the Software Design Gallery 第1回

『パソコン・プログラミング言語の歴史(1) - 行番号』

パソコンが登場して 25年たちますが、その歴史とともに歩んできた プログラマーも多いと思います。そこで今回は、 パソコンのプログラミング言語の歴史を振り返ることで、 プログラミング言語がなぜそのような形式になったのかを紹介ます。 そこからソフトウェア・デザインとは何かを追っていきたいと思います。

初期のパソコンには BASIC が付いていた

現在では、パソコンで多くの作業ができるように なりましたが、パソコンが登場し始めたころは まだマイコンと呼ばれており、 趣味やゲームのために使われていました。

当時のパソコンといえば、 NEC からは PC-6001、PC-8801、PC-9801、 シャープから MZ-700、MZ-1500(QuickDisk)、 MZ-2500、X1turbo、X68000(sprite) 富士通から FM-8、FM-TOWNS(CD-ROM)、 トミーから ぴゅう太(日本語BASIC)、 カシオ、ソニー、松下など各社から マイクロソフトとアスキーが作成した MSX 仕様の各マシンがありました。

個人的な話で申し訳ないですが、私の所有してきたパソコンは、 9歳のときに SHARP PC-1245、 翌年 NEC PC-6001mkII(4MHz)、高校生で NEC PC-8801MA(8MHz)、 大学生で NEC PC-9801NS-T(25MHz)、Fujitsu FM/V(75MHz)、 社会人になって Toshiba Libretto30(100MHz), 同 100(166MHz), Libretto ff(266MHz) と進化していきました。
初めて買ってもらった PC-1245 は、「ポケコン」(ポケモンではないぞ) と呼ばれる小型のものでした。工学部の学生が必ず持っていると 言われる関数電卓ぐらいのサイズです。 そのため、子供がゲームボーイをベッドの上で寝ながら遊ぶのと 同じ感覚で遊ぶことができました。 このようにしてコンピュータと出会ったため、 性能が良くても寝て使えなければと、 PC-9801NS-T の98ノートを買ってもらったり、 Libretto をメインマシンとして使っています。

このへんの古いパソコンの話をもっと知りたい方は、 検索ページで「マイコン」+「(機種名)」で検索すると、 多くの方の懐かしい思い出話のページにヒット しますのでそちらをご覧ください。

1980年代のパソコンは性能が悪く、とても仕事には使えなかったので、 購入した人のほとんどはゲームを楽しむために使っていたと思います。 その割に、値段は当時5万〜20万そこそこしたので、 高級なおもちゃと言われていました。 しかし、結構多くの友達が MSX パソコンを持っていました。 当時のゲーム機は、 ブロック崩しなど1つのゲームしか遊べないものが主流で、 任天堂のファミリーコンピューターが爆発的に売れ始めたころ でしたから、まだパソコンをゲーム機として使う人も多かったのでしょう。

パソコンとゲーム機の一番の違いは、 プログラムができるかどうかでした。当時のパソコンは BASIC というプログラミング言語が標準で搭載されていたので、 パソコンを買えばすぐにプログラミングができる環境でした。 というより、パソコンを普通に起動すれば、BASIC の環境になるので、 BASIC を使わないことにはパソコンが使えないといった感じでした。 そのため、ファミコンでもついにファミリーBASIC なるものが 売られてしまいました。結局プログラミングするには非力すぎたので 普及しませんでしたが。

当時のパソコン雑誌には、必ずプログラムリストがついていて、 自分のパソコンに打ち込んで楽しむことができました。 少々面倒なのですが、タダで新しいゲームができるようになるので みなさん結構やってました。 長いプログラムを打ち込んで自慢にしている人もいましたね。 現在ではブラウザのスクリプトを使ってプログラミングができますけど、 フリーソフトが簡単に手に入るので、 プログラミングする人はあまりいませんね。

BASIC は、現在の Visual BASIC とは全然違いますが、 当時のプログラミング言語の中では、 いちばん初心者にもわかりやすい言語として評価されていました。 それに、少ない記憶容量で実行できるという点が 非力なパソコンに向いていたといえます。

では、ここで、BASIC とは、どういったプログラミング言語なのか見ていきましょう。

10 INPUT "あなたのなまえは?", N$    ' ユーザからの入力を N$ 変数に格納
20 IF N$ <> "あらし" THEN 50         ' 条件を満たせば 50行へジャンプ
30 PRINT N$;"アホ"                   ' ディスプレイに表示
40 GOTO 60                           ' ジャンプ
50 PRINT N$;"さまはエライ"
60 END                               ' プログラム終了
(コンピュータは、基本的に 10行から 60行のように若い番号から 順番に実行していきますが、GOTO などのジャンプ命令によって 順番が変わることもあります。)

これは、当時のプログラミング少年のバイブルであった 「こんにちはマイコン」(すがやみつる著)に書かれていた プログラムですが、コンピュータが人間を判断するという点で 非常にショッキングなプログラムでした。 AI(人工知能)のはしりですね。 上のプログラムを走らせると、「あなたのなまえは?」 と表示され、キーボードの入力待ちになります。 そこで「あらし」と入力すると「あらしアホ」と表示され、 それ以外、たとえば「さとる」と入力すると 「さとるさまはエライ」と表示されます。

C 言語では、上記のプログラムは次のようになります。
#include  <stdio.h>
#include  <string.h>

void  main( void )
{
  char  name[100];

  printf( "あなたの名前は?" );            '10 行(1)
  scanf( "%s", name );                     '10 行(2)
  if ( strcmp( name, "あらし" ) == 0 )     '20 行
    printf( "%sアホ", name );              '30 行
  else                                     '40 行
    printf( "%sさまはエライ", name );      '50 行
}                                          '60 行
C 言語では BASIC の特徴である、10〜60 という行番号が 無くなっています。

行番号はコンピュータが実行する順序を示しています。 なぜこれが必要だったかというと、 当時のパソコンが1行分の文字を入力してリターンキーを 押すことでメモリに入力していたからです。 なぜ、リターンキーによって入力していたのかは、 コンピュータの構造によるところが多いと思われます。 次の章で詳しく見ていきましょう。

行番号が消えるまでの長い道のり

BASIC に行番号が付いていたのは、なぜでしょうか。 その手がかりを知るために、コンピュータの内部構造を少し見てみましょう。

パソコンの基本的な内部構造は次のようになっています。

プログラムを実行するときは、メモリにプログラム(命令)を格納しておき、 命令を1つ1つ読み込んで実行していきます。 メモリには、CPU が直接理解できる機械語が入っています。
メモリアドレス機械語(*1)ニーモニック意味
000001F0mov a,01レジスタ A に 1 を格納する
000202F1mov b,02レジスタ B に 2 を格納する
0004AFadd a,bレジスタ A と B を足して A に格納する
(*1)ここにかかれている機械語はイメージです。実際の値とは関係ありません。

メモリに格納されている機械語の実体は数値です。 それぞれの数値は CPU が動作する内容に対応しています。 その内容をニーモニックで表現します。 ニーモニックはアセンブリ言語にほぼ一致します。

パソコンが生まれる前は、 ワンボードマイコン(TK-80など)が発売されていました。 ワンボードマイコンは、パソコンのようなディスプレイが無い代わりに 数字だけ表示する LED が電卓のようにあり、 キーボードもテンキーだけで、 全体的に見ればパソコンの中に入っているマザーボード(緑色の板)が そのままむき出しになっているようになっています。 このように原始的な構造になっているため、 ワンボードマイコンは、CPU やメモリを直接操作できるという特徴があります。 その代わりに、コンピュータの内部構造に合わせた操作をしなければなりません。

ワンボードマイコンにプログラムを入力するときは、 入力するメモリアドレス(メモリの位置番号)を指定してから、 機械語を入力していきます。 ただし、1つの機械語を入力するたびに[入力]キーを押します。 これは、インターネットの検索ページにキーワードを入力して [検索]キーを押すのと同じことです。 プログラムを修正するときは、アドレスを指定してから、 修正する機械語を入力します。 プログラムを実行するときは、実行を開始するアドレスを、 プログラムカウンタ(PC) と呼ばれる特殊なレジスタに格納してから実行を開始します。
このように常にアドレスを意識しながら[入力]を押すという プログラミングを行っていました。

BASIC でプログラムを入力するときも、行番号を入力してから プログラムの1行を入力し、リターンキーを押すことで プログラムがメモリに格納されます。 アドレスが行番号に代わっていますが、 同じような考え方が BASIC に受け継がれていったことがうかがえます。 昔の FORTRAN も同様に行番号が存在しました。

また、アドレスや行番号は、プログラムの実行する順番を 表しているだけではありません。 条件によってプログラムを実行する(ジャンプする)場所を指定するときに、 アドレスや行番号を使用します。 たとえば、GOTO 30 のように「30行」にジャンプするなどです。

これらの理由ため、プログラムにおいて、 行番号は必須のものと考えられてきました。

しかし、行番号があると、プログラムの途中に命令を追加するときに、 問題が発生します。 次のように追加した命令に途中の行番号を割り当てたとします。
110 N = 10
115 M = N      ' 変数 M に取っておきたいので追加
120 PRINT N
これはこれで問題ありません。 最初のサンプルで行番号が 10 単位になっていたのはこのためですが、 この方法にも限界があります。10行以上の命令を 追加することができないからです。 もし、追加しようとするのなら、行番号を振りなおすか、 行番号があいているところへ 一度ジャンプしてから戻ってくるようにしなければなりません。

他にも、命令を追加すると、10行ごとにならなくなるため、 見た目がわるくなるという欠点もあります。 そこで、BASIC では、RENUM というコマンド命令 (プログラムに入れないで直接実行する命令)が追加されました。 RENUM は、プログラムの行番号を 10 ずつに整列してくれるという 優れものです。後ろに詰まっている命令も自動的に 行番号を増やしてくれるのです。 このため、RENUM を繰り返すことで10行以上の命令を 簡単に追加することができるようになりました。

これで解決したように思えるのですが、 そもそも RENUM が必要なのは行番号があるからです。 行番号を無くしてしまえば必要ないのです。 RENUM を実行する必要も無いのです。 それでは行番号をなくす方法を考えてみましょう。

行番号が存在する理由の1つは、命令を実行する順番を示すためです。 しかし、よく考えると、実行する順番が上から下へというのは 明らかです。それでも必要だったのは、プログラムを入力するときに、 リターンキーを押していたからです。 現在のプログラミングのように、ソースファイル(プログラムを記述した ファイル)をあらかじめ作っておき、それを読み込んで実行すれば リターンキーによる入力は必要なくなります。 しかし、そのためには、テキスト・エディタが使えるようになることと、 実行環境とテキストエディタ・プログラムの切り替えが できるようにならなければなりません。 MS-DOS が登場してそれらが実現できるようになる 1990 年前後になるまで、 パソコンの世界では、行番号が消えることはありませんでした。

行番号が存在するもう1つの理由は、 ジャンプ先を示す必要があることです。 しかし、ジャンプ先を示すのに番号でなければならないことは無いはずです。 その目印さえあればいいはずです。 機械語に最も近いアセンブリ言語や COBOL では、 そのためのラベル付けができるようになっています。
start:             ; プログラム開始ラベル
    mov   a,10
    cmp   a,0
    jgt   output   ; output の行へジャンプ
    halt
output:            ; ジャンプ先のラベル
    add   a,1
    call  print
    halt
行番号が無くなってすっきりしていますね。

そして BASIC にも、ラベルがサポートされていきました。
110 N = 10
120 IF N > 0 THEN *OUTPUT   '条件を満たせば 140行へジャンプ
130 END
140 *OUTPUT  PRINT N+1

ただ、ラベルを付けるということは、ラベルの名前を付けなければ ならないということです。
10 INPUT "あなたのなまえは?", N$    ' ユーザからの入力を N$ 変数に格納
20 IF N$ <> "あらし" THEN L1         ' 条件を満たせば 50行へジャンプ
30 PRINT N$;"アホ"                   ' ディスプレイに表示
40 GOTO L2                           ' ジャンプ
50 *L1  PRINT N$;"さまはエライ"
60 *L2  END                          ' プログラム終了
50、60 行目のように、その行に特に名前が付けられるような意味が無いときは 困ってしまいます。L1, L2 のように行番号とあまり変わらない名前を つけざるを得ないでしょう。

さらに、ラベル名は、プログラム全体で唯一の名前をつけなればならないので、 管理する手間が発生してしまいます。 インターネットのドメイン名を JPNIC などの管理団体が管理して いるように、唯一の名前を管理するのは大変なことです。 それぐらいなら、RENUM が使える行番号を使っていたほうが 楽でしょう。


あらゆるジャンプ先にラベルをつけなければならない という問題が解決するには、プログラム言語史上、 重大なパラダイムシフトが起きなければなりませんでした。 それについては次回紹介したいと思います。

← Prev (00)

(02) Next →


written by T's-Neko May.2000  - From Sage Plaisir 2