- ベストアンサー
最初のアセンブラ
人間がハンドアセンブル際にアセンブリ言語と機械語の対応表を見比べて翻訳する作業を、コンピュータの黎明期に機械語で最初に作られたアセンブラはどのように行っていたのかということを教えて下さい。 プログラミング言語の歴史を考えてみると、(フォン・ノイマン型)コンピュータの黎明期では全てのプログラムは最初人間が直接真空管やディップスイッチのオン/オフを切り替えることで、機械語でプログラムを入力していたと思います。その後アセンブラが開発されたことで、人間はパンチカードやカセットテープなどを通してアセンブリ言語でプログラミングを行えるようになったと聞きました。 アセンブリ言語は機械語と1対1で結びついたもので、アセンブラはアセンブリ言語を機械語に翻訳するのだと言うことは分かります。しかし、パンチカードやカセットテープで入力したアセンブリ言語も、コンピュータにとっては根本的には0/1(スイッチのオン/オフ)という点では変わりはなく、最初のアセンブラはその0/1をどのようにして正しい機械語の0/1に変換することが出来たのでしょうか? 少し質問の意味が分かりにくいかもしれませんが、例えば MOV B, A //Bレジスタの内容をAレジスタに送る といったアセンブリ言語は、機械語では 01000000 に相当するかもしれません。しかしコンピュータがパンチカードを読み込んだ時点では 01010100 といった信号として入力されるとしたら、機械語で最初にアセンブラを作成した人はどのようにしてそれを適切な機械語(ここでは01000000)に翻訳出来たのでしょうか? 想像では最初に機械語で非常に超簡単なアセンブラの原型とも言えるプログラムを作って、それを元にした簡単なアセンブリ言語(の原型)でより高度なアセンブラを作る、といったことを繰り返していまのアセンブラが開発されていったと思いますが、では最初のアセンブラの原型とはメモリ上ではどのように実現されていたのか、ということが気になったので質問させていただきました。アセンブリ言語で実際にプログラムのイメージはこんな感じでは?ということを書いて下さっても構いません。 よろしくお願い致します。
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
No.5です。補足質問にお答えします。 色々資料をあさっていたので遅くなってしまいました。 > 2進コードへの変換はテーブルを探す方法と変換表で一発で探す方法というのがあまりよく理解出来ないのですが 普通はテーブルサーチ(逐次検索、2進検索)というのを使います。 しかしスピードが遅いのでハードレベルやOSレベルでは一発検索(変換表)もよく使われます。 例えば確か「文字A」はEBCDICでは(C1)16=193、ASCIIでは(41)16=65だったと思います。 つまり表の65+1番目に193を入れた表と表の193+1番目に65を入れた2つの表があれば 検索無しに「A」の一発コード変換が出来るのです。 > 私が一番知りたい答えは、具体的にその120バイトに何(どういった命令)が書かれていたか?ということです。 はい、私もそれが知りたいです。 しかし、色々調べたり推測したりしましたが結論には至りません。 当時はメーカーとしてもトップシークレットだったと思いますから。 2進コード→文字コード→ニモニック変換→機械語 テーブルサーチや変換表がありますが、一長一短があります。 変換速度とテーブルの大きさです。 最近の検索技術では2分木というのも使われますが当時どのようになっていたかは判りません。 > 初期のIBMだとSystem/360だと思いますから命令語長が2、4、6バイトの何れかです。 実はIBM1800というプロコン(現在の分類ではミニコン)16ビット機でした。 科学技術計算用の1130の兄弟機でした。 世界中に1000台くらい売れていたのでベストセラーですね。 余談ですが日立のプロコン1号機HITAC7250は1800のデッドコピーでした。 命令語は2バイト、4バイトのみです。 > 120バイトに入れられる機械語命令は約40~60命令ぐらいですよね。 > アセンブラでプログラムした事のある人は分かると思いますが、さすがにその命令数で簡易なアセンブラも組めません。 > ニーモニックの文字列比較する文字を入れる事さえ無理なバイト数です。 実は私も同じ意見です。 ここ数日?考えていたのですがある考えにいたりました。 DC命令やEQU命令などの擬似命令を読み込んで解析し、メモリーに展開できれば 比較的簡単に機械語命令を作り上げることが出来るのではないかと。 今の計算機と違ってそのころはデーター部を実行したり(例えばパッチ)、命令語を実行時に書き換えるなどは 可能かつ日常茶飯事でしたから。 私の推測の結論は120バイトの機械語で擬似命令を解析し機械語で本物のアセンブラーをメモリー上に展開し、 これにコントロールを渡すことで本物のアセンブラーを起動させたのではなかろうかということです。 吊橋を掛けるときにヘリでロープ(または細いワイヤー)を張ってそのあと順々に太いロープを牽引していきますが これに似ていますね。 あくまでも質問者さんの好奇心に応えて40年ほど前の淡い記憶で書いているだけなので本当は的外れかも知れません。
その他の回答 (10)
- zwi
- ベストアンサー率56% (730/1282)
一番古いのでS/360系の互換機(FACOM230/25だったかな?)とかしか触ったことがないので、「IBM 1800」は未知のマシンですね。 wikiにありましたが、これででしょうか? http://ja.wikipedia.org/wiki/IBM_1800 1180の原型の1130のエミュレータもあるみたいですね。 http://ibm1130.org/ >私の推測の結論は120バイトの機械語で擬似命令を解析し機械語で本物のアセンブラーをメモリー上に展開し、これにコントロールを渡すことで本物のアセンブラーを起動させたのではなかろうかということです。 これは、また別のカードからアセンブラーを読んだって事ですか?それとも意味が違います? 紙テープから大量にコードを読んだのなら納得なんですけど。私の経験では実際に紙テープに機械語を書き出したり紙テープから読み込んだりしたし。
- zwi
- ベストアンサー率56% (730/1282)
>C言語などで実装するならまだしも、アセンブリ言語でこれを実装するとなると相当命令数が長くなりそうな気がします・・(アセンブリの経験はほぼないのではっきりとは分かりませんが・・) アルゴリズムは合っていると思います。 まぁ、それでも簡易なアセンブラなら1KBとかで組めると思いますよ。実際にやってみないと分かりませんが。 H8マイコン等で実際に簡易アセンブラを作ってみるのが一番理解できるかもしれませんね。
お礼
ご回答ありがとうございます。 なるほど、アルゴリズムはやはりこんな感じなのですね。 マイコンの経験はほぼないですが、根本的な事柄を理解するのにも役に立つと思うので、ぜひいずれ挑戦してみたいと思います。
- zwi
- ベストアンサー率56% (730/1282)
>最初のアセンブラーは120バイトの機械語でプログラムされていたということは分かりました。 議論する気はないんですが、初期のIBMだとSystem/360だと思いますから命令語長が2、4、6バイトの何れかです。 http://journal.mycom.co.jp/column/architecture/056/index.html 平均1命令4バイトよりちょい少ないと仮定して120バイトに入れられる機械語命令は約40~60命令ぐらいですよね。アセンブラでプログラムした事のある人は分かると思いますが、さすがにその命令数で簡易なアセンブラも組めません。ニーモニックの文字列比較する文字を入れる事さえ無理なバイト数です。う~ん。なぜカード一枚でアセンブラが起動できるかわかりません。 で、簡易アセンブラのコードですが概念だけ。 [命令テーブル] OPコード(1バイト) 文字列長(1バイト) 文字コード : 文字コード を命令数分。 [ニーモニックコード] (1)MOV (2)A,B (1)入力されたニーモニックの文字コードと命令テーブルの文字コードが一致するものを探し、一致した命令テーブルの命令(OP)コードを得る。 (先頭文字から空白までの文字で一致するものを命令テーブルから検索) (2)オペランドを解析して、どのレジスタを対象としているかオペランドコードに変換する。これもswitch~case的な処理を行う必要があります。
お礼
ご回答ありがとうございます。 >120バイトに入れられる機械語命令は約40~60命令ぐらい >ニーモニックの文字列比較する文字を入れる事さえ無理なバイト数です。う~ん。なぜカード一枚でアセンブラが起動できるかわかりません。 たしかに40~60命令ぐらいしかないとしたら本当に簡易アセンブラが実装出来るのかなぞですね・・・ >で、簡易アセンブラのコードですが概念だけ。 ありがとうざいます、この概念だけでもほぼ90%私の知りたかった答えを得ることが出来ました。 残りの10%ですが、 >先頭文字から空白までの文字で一致するものを命令テーブルから検索 とありますが、もう少し具体的なイメージとしては、1文字が1バイトだとすると、 (1)ニーモニックの左端から1文字(1バイト)ずつ、まず命令テーブルの最初の命令の文字コードと比較が行われる (2)空白まで全ての文字コードが一致すれば、一致した命令テーブルの命令コードを得る (3)一致しない場合は、命令テーブルの次の命令の文字コードと比較していく((1)にループする) (4)命令テーブルの最後まで一致するものがなければエラー といった感じでしょうか?C言語などで実装するならまだしも、アセンブリ言語でこれを実装するとなると相当命令数が長くなりそうな気がします・・(アセンブリの経験はほぼないのではっきりとは分かりませんが・・) 好奇心からここまで突っ込んだ質問で申し訳ありませんが、皆様のご親切な回答に感謝しております。
- ymmasayan
- ベストアンサー率30% (2593/8599)
No.5です。 ご指摘がありましたので補足します。 ここでは議論が禁じられていますのでできるだけ議論にならないように書きたいと思います。 > 「これは80×12穴=960ビット=120バイトの機械語です。 > 恐らくこれが最小限のアセンブラーだったと推測されます。」 > 機械語=アセンブラーみたいに成ってますが、これはどちらなんでしょうか? 機械語で書かれた(あるいはアセンブルされた)アセンブラー(プログラム)という意味です。 つまり翻訳ツールです。 > 私から見たらニモニック→マシン語変換されないんで、ただのローダーだと思うんですが。 1枚だけバイナリーのカード(コールドスタート)を読んでそのあとにはまさしくアセンブリー言語で書かれたカードを積んでいました。 このことから960ビットのカードはアセンブラーとしか考えられないのです。 もう少し詳しく言うとこれはあくまでもシステム生成時の話です。 HDDに何もない状態ですので 1.まずコールドスタートのあとアセンブリー言語で書かれた仮OSにEQUで沢山のパラメータを与えてアセンブルします。 2.結果としてパンチカードに2進出力された本物のOSが出来てきます。 3.そのOSをHDDに読み込み本番準備が完了です。 4.通常のスタートはHDDからローダーを使って行います。 以上のようにコールドスタートカードと仮OSの間にアセンブラーらしきものが存在しなかったのです。 アセンブラーがファームウェアーで入っていたなどは考えられません。 何しろメインメモリーが128KBMAXの磁気コアでしたから。 > 「(1)2進数で読み込んだカードを文字コードに変換する。」の事ですが、初期はCPUで変換してたんでしょうか? これも確かなことはいえませんがカードリーダーが2進カードと文字カードを差別無く読んでいたことから考えて CPUで変換していたと考えるのが自然だと思います。 コンソールのキーボードも一文字づつ割り込みを掛けて読んでいましたから。 キーボードにCPUが内蔵されて文字列転送されるようになったのはかなりあとの話です。
- zwi
- ベストアンサー率56% (730/1282)
すいません、ymmasayanさん質問者のmiyaken912さんを混乱させたくないので疑問というか質問です。 2.の「これは80×12穴=960ビット=120バイトの機械語です。恐らくこれが最小限のアセンブラーだったと推測されます。」 なんですが、機械語=アセンブラーみたいに成ってますが、これはどちらなんでしょうか?私から見たらニモニック→マシン語変換されないんで、ただのローダーだと思うんですが。文字通りIP(Initial Program)なのではないでしょうか。 3.の「(1)2進数で読み込んだカードを文字コードに変換する。」の事ですが、後期のパンチカードリーダかつOS下でしか使ったことがないのでが、カードリーダIOチャネルから読み込んだ時点でEBCDIC文字コードになっていた気がするんですが、初期はCPUで変換してたんでしょうか? かれこれ私がかかわったのは20年以上前ですが。
- ymmasayan
- ベストアンサー率30% (2593/8599)
1960年頃からコンピューターを触ってきました。 全ての機種を知らないのでかなり推測もありますが。 まず、最初に基本的なところから。 1.コンピュータを語るには、コンピューターの本能と知能を分けて考える必要が有ります。 本能・・電源を入れただけで出来ること。人間の赤ちゃんが生まれた状態に相当します。 知能・・あとから教えることで出来るようになることです。 実はこの本能と知能の分担が時代により、またメーカーにより、機種により大きく違うのです。 余談ですがPC初期のNEC-PC8001などは32KB位のROMが搭載してあって 電源を入れるとBASIC(インタープリター)でいきなり作業が出来ました。 初期のコンピュータは本能がほとんど無く、スイッチとランプで入出力してました。 もちろん機械語オンリーです。 しかし機械語は人間に難解なのでニモニック(記号化)という考えが生まれました。 ニモニック http://www.atmarkit.co.jp/icd/root/92/189003792.html しばらくはこのニモニックを使ってプログラミングしハンドアセンブルで機械語入力していました。 その後ハンドアセンブルを自動化するようにしたのがアセンブラーです。 2.本能と知能について初期のIBMマシンの例をあげてみましょう。 本能といえばIPL(Initial Program Loader)でIBM80欄カードを1枚だけ読み込む機能でした。 これは80×12穴=960ビット=120バイトの機械語です。 恐らくこれが最小限のアセンブラーだったと推測されます。 あとはパンチカード1枚を(80文字)として読み込んで知識をどんどん膨らまして行ったのでしょう。 3.アセンブラーの基本構造は (1)2進数で読み込んだカードを文字コードに変換する。 (2)文字列を分析し対応する2進コードに変換する。 でいいはずです。 2進コードへの変換はテーブルを探す方法と変換表で一発で探す方法があります。 例えばA=ASC(31)=49→表の49番目が’A’ 4.簡単なアセンブラーを使ってもっと複雑なアセンブラー例えばマクロアセンブラーを作れることは質問者さんの言われるとおりです。 5.現在では「コンパイラーコンパイラー」という本がたくさん出ています。 お察しの通り、新しいコンパイラーを作るための基本的なコンパイラーのことです。 余談ですがC言語というのもUNIXという巨大OSを書くために作られたものです。 C言語はプロが使うもので素人が使うと大怪我をするといわれるのもこのあたりから来ています。
お礼
詳しいご回答ありがとうございます。 >これは80×12穴=960ビット=120バイトの機械語です。 >恐らくこれが最小限のアセンブラーだったと推測されます。 >3.アセンブラーの基本構造は > (1)2進数で読み込んだカードを文字コードに変換する。 > (2)文字列を分析し対応する2進コードに変換する。 私の知りたかった答えに最も近い回答です。さらにで恐縮ですが、このアセンブラーの基本構造について、より突っ込んだ質問をさせていただいてもよろしいでしょうか? 最初のアセンブラーは120バイトの機械語でプログラムされていたということは分かりました。2進コードへの変換はテーブルを探す方法と変換表で一発で探す方法というのがあまりよく理解出来ないのですが、私が一番知りたい答えは、具体的にその120バイトに何(どういった命令)が書かれていたか?ということです。 >(1)2進数で読み込んだカードを文字コードに変換する。 というのは、例えば僕の推測だとメモリ上に上から順に A: 01100000(b)、60(H) B: 11011010(b)、ba(H) : Z: 11010110(b)、d6(H) みたいな感じに1バイト×(A~Zまで)26のテーブルを作り、テーブルの先頭アドレスからパンチカードから読み込んだ値をオフセットとして加えたアドレス(ASCIIの表でAなら49がオフセット)の内容が変換された文字コードになる。といったような仕組みでしょうか? さらに >(2)文字列を分析し対応する2進コードに変換する。 の、文字列の分析というのはアセンブリ言語で書くとどういったロジックとなるでしょうか? 「(1)2進数で読み込んだカードを文字コードに変換する」で変換した文字列が例えば「MOV B,A」だったとしたら、その分析(つまり文字列の一致判断?)というのはアセンブリプログラムのレベルではどのように書かれるでしょうか?だいたいの雰囲気でいいので、可能な限りご回答願えればと思います。 一般にはどうでもいいかもしれない疑問を深く追究してしまい申し訳ありませんが、どうぞよろしくお願い致します。
- zwi
- ベストアンサー率56% (730/1282)
大体考えは合ってます。 >一致した場合はその命令の機械語をプログラム領域として確保してあるメモリアドレスに書き込む。この場合は対応表から01010100がMOV B,Aと一致するので01000000を翻訳した機械語プログラムとしてあるメモリアドレスに書き込む まぁ、最初のころのコンピュータはメモリが少ないので直接パンチテープあたりに機械語コードを直接書き出していた可能性が高いです。 >妙な質問かもしれませんが、情報工学を独学で勉強しており、また初心者ゆえC言語やPHPなどのプログラム自体は書けますがそもそも非常に根本的なところでプログラムやコンピュータというのがどう発展してきたのかというところに興味があります。どうぞよろしくお願い致します。 歴史というか、CPUの基礎的なことを勉強したほうがコンピュータの理解には良いかもしれません。 アセンブリ言語スタートブック http://www.amazon.co.jp/gp/product/4774138428/ CPUの創りかた(表示はアレですが中身はまじめです) http://oshiete1.goo.ne.jp/kotaeru_reply.php3?q=5028460 コンピュータアーキテクチャの話 http://journal.mycom.co.jp/column/architecture/index.html 基礎から学ぶコンピュータ http://rryu.sakura.ne.jp/compfund/index.html
お礼
ご回答ありがとうございます。 参考になるリンクや本を紹介して下さりありがとうございます。この中でCPUの創りかたは既に読み、ほぼそこに書いてある内容は理解していると思います。それに続く問題として、では一番最初にハンドアセンブルを自動化したアセンブラというのは、アセンブリ言語で具体的にどのようにプログラムされたのだろうかと思いました。 他のリンクもぜひ読んでみようと思います。
- ralf124c
- ベストアンサー率52% (232/446)
最初のコンピュータを触ったというほど古い人間ではないのですが、某大手電機メーカーグループ会社で勤務していた際は工場内に過去機種のセンターが有り、担当機種の保守を行っていました。 中には骨董品と思われるメインフレーム(大型計算機)があり、プログラムの基本入力はトグルスイッチやロータリースイッチ(MOVやLDやADDなど基本命令を指すもの)とプッシュボタンを利用していました。 アセンブラは各機種のドキュメントにニモニックコード表が付いていて、アセンブラのソースで書いたものを対応表から16進数の機械語コードに直し(ハンドアセンブル)、さらに2進数から8個のトグルスイッチで01をセットしてプッシュボタンで少ないメモリ領域にデータ入力を行っていました。 ただし立ち上げの際は、OSを含む全プログラムをそうやって入れているとたいへんなので、通常はIPLプログラムを特定にアドレス(アドレス入力もトグルスイッチ)に対して先の方法で手入力して、紙テープなど外部装置から一気に流し込むというやり方で起動を行っていました。 慣れると16進ダンプコードの処理内容がなんとなくわかるようになりますが、ハンドアセンブルの際は表が手放せませんでした。 ハード設計者のひとりに話を聞いた際には、開発時にはコードをある程度憶えていて(自分で命令を決めて作ったのですから)結構スラスラと書いていたそうです。
お礼
ご回答ありがとうございます。 一番最初のアセンブラの翻訳ロジックではありませんが、初期のコンピュータに関する知識として役に立ちました。
- don_go
- ベストアンサー率31% (336/1059)
>機械語で最初にアセンブラを作成した人はどのようにして >それを適切な機械語(ここでは01000000)に翻訳出来たので >しょうか? 全て手作業で行います。 機械語に対応するコードを全て暗記又はコードの対応表を参照 して機械語のプログラムを作っていきます。 #ジャンプ先等のアドレスも全て手計算
- zwi
- ベストアンサー率56% (730/1282)
最初のアセンブラですか? あくまで想像ですが、機械語で書いたと思います。 機械語でアセンブラプログラムを作って、そのプログラムがパンチカードやテープからアセンブラソースコード(テキストコード)を読み込んでアセンブルしたのです。 例えば、マイコンの初期段階では2進コードを入力SW(8ビット分!)で直接RAMに書き込むハードを作ってそれでマシン語を直接入力してましたしね。汎用機でも直接マシン語を入力する方法をカスタマーエンジニア(CE)さんに教えてもらったことがあります。
補足
ご回答ありがとうございます。 >機械語でアセンブラプログラムを作って、 ということですが、質問の意図としてはそのアセンブラプログラムはどのようなロジックになっているのだろうか?ということです。 僕の推測ではメモリのデータ領域に読み込まれた01010100というデータが、アセンブラによって01000000に変換されるのには、一つずつ01010100と各命令とをCMP命令などで比較していき、当てはまった場合は該当する機械語命令を書き込むといった流れになっていると思ったのですが、この推測は正しいでしょうか? つまり、 ・アセンブラを実行 ・アセンブラはパンチカードから入力されたプログラムの最初のデータをレジスタに送る ・CMPでレジスタの内容(この場合は01010100)と各命令の対応表にあるデータ(0010011ならLOAD命令,0010100ならADD命令というように)が一致するか一つずつ比較する ・一致した場合はその命令の機械語をプログラム領域として確保してあるメモリアドレスに書き込む。この場合は対応表から01010100がMOV B,Aと一致するので01000000を翻訳した機械語プログラムとしてあるメモリアドレスに書き込む ・次の行のアセンブリプログラムを読み込み、上記を繰り返す といった流れになるのでしょうか? 妙な質問かもしれませんが、情報工学を独学で勉強しており、また初心者ゆえC言語やPHPなどのプログラム自体は書けますがそもそも非常に根本的なところでプログラムやコンピュータというのがどう発展してきたのかというところに興味があります。どうぞよろしくお願い致します。 といった感じでしょうか?
お礼
補足に加え、いろいろと調べて下さりまことにありがとうございます。 >つまり表の65+1番目に193を入れた表と表の193+1番目に65を入れた2つの表があれば検索無しに「A」の一発コード変換が出来るのです。 なるほど!たしかにそうすれば検索は必要ありませんね、非常に勉強になりました。 >DC命令やEQU命令などの擬似命令を読み込んで解析し、メモリーに展開できれば 比較的簡単に機械語命令を作り上げることが出来るのではないかと。 >私の推測の結論は120バイトの機械語で擬似命令を解析し機械語で本物のアセンブラーをメモリー上に展開し、 これにコントロールを渡すことで本物のアセンブラーを起動させたのではなかろうかということです。 DC命令やEQU命令などの疑似命令をよく知らないので完全にはおっしゃる内容を理解することが出来ませんが、段階的にまず120バイトにおさまる非常に小さなプログラムが最初にあり、そのプログラムで大きなアセンブラーのプログラムを読む込むことが出来るようにしたということは分かりました。 テーブルサーチや、またアセンブラー読み込みの方法などとても勉強になりました。ご親切にいろいろと調べて下さり感謝しております。