Objective-C への準備 その1
目次
優秀プログラマに必要なコンピュータの真髄の理解
1. はじめに
スマートフォンやタブレット向けのアブリケーションを作ろうとしている人にコンピュータの本質的な仕組みを紹介する資料です。具体的には機械命令語の設計思想と特徴を丁寧に解説します。主題ではありませんが、機械命令語を実行するハードウェアの諸機構についても必要最小限の解説をします。
*できるだけ簡単に解説していますが初学者には難しい言葉や専門用語も使っていますので文字リンクを見ながらゆっくり読み進めてください。
プログラムはJavaやCやPascal、あるいはObjective C などの高級言語で書きます。アセンブリ言語でプログラムを書く必要はありません。情報処理技術者試験でアセンブリ言語の問題が必須だったこともありましたが、遥か昔のことになりました。
今日、アセンブリ言語でプログラムを書かねばならない人は限られるでしょう。しかしだからと言って、機械命令語の知識が不要と断じるのは近視眼的です。
ソースプログラムの記述に高級言語が使われるものの、コンパイラで翻訳された実行形式プログラムは機械命令語による記述に変わります。だから機械命令語の知識が必要だ、と言うことではありません。
実行形式プログラムの記述に使われる機械命令語について、何故そのような仕様で設計されているかについての理解が、良いプログラムを書くのに必要だからです。
高級言語の仕様は機械命令語から完全に独立したものではありません。機械命令語の影響を強く受けています。
機械命令語の設計思想を理解し、その特徴を活かした形で高級言語によるプログラムを書くべきなのです。子どもは父母だけを見て生きるのでは不十分です。2組の祖父母も理解しないとよい生き方はできないのです。
本資料に続く第2編では数表現や演算方法を解説し、第3編ではプログラムにおける基本構成要素(ループや条件判定など)を機械命令語の切り口から解説します。
2. コンピュータとは
コンピュータは機械命令語で書かれたプログラムを実行する機械です。それ以上でもそれ以下でもありません。
主記憶装置には磁気ディスクなどから読み込んだプログラムが記憶されます。
プログラムを起動するときは、当該ブログラムの起動位置にある機械命令語を先頭にして、順にコンピュータに読み込まれ、命令コードが解釈され、演算対象のデータを準備した後、実行(演算)されます。
なお次の実行される機械命令語は先行する機械命令語の後続位置にあります。この位置は先行する命令語の先頭番地に当該命令語の語長を加えることで求められます。この番地情報は一般に“プログラムカウンタ”と呼ばれるレジスタに収容されていることはご存知だと思います。
3. オペレーティングシステム
図1は、コンピュータハードウェア、オペレーティングシステム(OS)、そしてアプリケーションプログラムの関係を示すものです。
(1) 事物
一般的に“事物”とは、“こと”や“物(もの)”を指します。例えば大学では、教室や体育館や図書館の本などは“もの”で、講義は“こと”と言えるでしょう。また学生の科目ごとの成績や現住所・帰省先・出身高校名などは学生に付属する“情報”です。これもやや乱暴ですが、物理的実体がないので“こと”と同じ扱いにします。
(2) 管理者と利用者
“こと”や“もの”には、維持管理する人と、利用する人がいます。オペレーティングシステムは管理する人に相当し、実行されるプログラムは直接あるいは間接に管理対象を利用する人に相当します。
(3) 管理対象 その1
計算機システムの場合、“もの”には、主記憶装置・磁気ディスク・通信機構・印刷装置・プロセッサ・センサーなどのハードゥエアのほか、主記憶装置や磁気ディスク装置がもつ記憶領域、ファイルやファイル中のレコードなどがあります。記憶領域は使用中の領域も未使用の領域もオペレーティングシステムが管理します。時刻のほか経過時間も管理する場合があります。
(4) 管理対象 その2
ジョブとかプロセスというプログラムの実行単位のほか、スレッドやタスクと呼ばれる実行単位も管理の対象です。
(5) 管理者権限
“こと”や“もの”には利用者に開放できないものがあります。乗客に電車の運転をさせられませんし、経営会議の場に部外者を入れることもできません。コンピュータも事情は同じです。磁気ディスクの読み書きを利用者の自由にはさせられません。読み書き可能な記憶領域を制限し、実行できる機械命令語を制限する仕組みが必要です。図1では、カーネル部だけが“特権命令”を使って管理者権限を行使することを示しています。
(6) 接続規
図1では、カーネルとハードウェア、カーネルとアプリケーションプログラムとf接続関係があります。これらには、接続して動作するための規約が必要です。優れたプログラマは絶えず接続の規約を意識している筈です。
4. 計算機アーキテクチャ
コンピュータには、命令セットのアーキテクチャと、命令セットを実行する機構としてのコンピュータアーキテクチャとがあります。
4.1 命令セットアーキテクチャ
どのコンピュータも自身が解釈し実行できる機械命令語の組(セット)をもちます。命令セット(Instruction Set)といいます。この命令セットに関する技術の体系を命令セットアーキテクチャといいます。命令語の表現形式とデータ処理機能、データの表現形式、プログラムカウンタを含むレジスタの種類や構成などがその対象となります。図2はその例を体系的に示したものです。
(1) 土台の部分では命令セットが対象とする情報の単位を定義します。ビットからはじめ、バイト、半語、語、倍長語などです。次にデータの種類や形式を定義します。整数や実数の構成、ブール値や文字・文字列などのデータ形式や命令語が扱う文字コードを定義します。
(2) 次にコンピュータシステムの論理的な構成を定義します。主記憶を参照する単位、レジスタの種類とビット構成、主記憶の参照アドレスの形式、機械命令語の形式などです。
(3) 次に機械命令語の機能を定義します。主記憶やレジスタ間のデータ転送命令をはじめ、四則演算、論理演算、シフト演算などの命令が続き、条件分岐・関数呼び出し・ループ制御などの流れを制御する命令が続きます。OSカーネルのために、入出力動作に関連する命令、システムの制御と管理のための命令群の定義も必要です。
(4) システム制御
入出力動作の終了やタイマーの更新などのための割り込み処理、コンピュータの初期設定などの仕様も命令セットアーキテクチャの範囲です。
4.2 コンピュータアーキテクチャ
コンピュータは機械命令語で記述されたプログラムを実行する機械でした。簡単に言えば、コンピュータアーキテクチャとは機械命令語を実行する機構の組織的体系や設計思想のことです。
(1) 機械命令語の基本的な実行形式
機械命令語の実行を機能の面から分けると、命令語の読み出し、命令コードの解読、演算データの準備(読み出し)、演算の実行、結果の格納(書き出し)とに分けられることを説明しました。
(2) キャッシュメモリ機構
命令の読み出しやデータの読み出しは主記憶装置に対して行われます。そこにしかないからです。主記憶の参照(読み書き)は、プロセッサ内のレジスタの参照に比べて長い時間がかかります。この時間を短縮するため命令キッシュやデータキャッシュという高速メモリをプロセッサ内に設けます。キャッシュメモリにあれば、命令語もデータもレジスタから読み出す場合とほぼ同じ時間で読み出せるのです。
(3) 命令パイプライン機構
先行する命令の実行終了後に後続する命令の実行を開始する命令実行方式は単純ですが時間がかかります。それに対して、例えば命令の実行工程を均一時間の10工程に分け、後続する命令群の処理を工程単位に並列に実行すると、理想的には処理速度は10倍になります。命令パイプラインとは、工場の流れ作業のように、命令の実行を各工程単位に並列に行うことによって処理速度を高める手法です。パイプ中を流体が流れるのに似ていることから命令パイプライン方式と言います。先行する命令が後続する命令のパイプライン処理に干渉することがあるため、それらの検出と回避のために複雑な機構になります。
(4) 仮想記憶機構
仮想記憶機構は主記憶装置の容量を仮想的に拡大して見せる機構です。キャッシュメモリとは異なり、ソフトウェアとハードウェアが連携してこの機構を実現します。大規模な機構なので社会人の技術者でも理解するのは難事です。本稿では詳細な説明は略します。
(5) 演算方式と演算回路構成方式
数値演算を高速に行うための演算方法と演算回路の構成方法についての技術体系があります。その成果がコンピュータの演算回路に反映されています。基本的には乗算は加算の繰り返しであり、除算は減算の繰り返しです。乗除算命令は加減算命令に比べて時間がかかるのです。高速な計算方法を求める努力が積み重ねられてきましたが、それらの詳細は本資料では省略します。
5. 命令セットアーキテクチャ
命令セットアーキテクチャは、命令セットの設計に関する科学技術の体系であり、命令セットが保証する情報処理機能の体系でもあります。読者の多くは後者の立場で命令セットアーキテクチャに関わるのですが、命令セットの開発者の視点から得られる知見は優れたプログラマにも不可欠です。
5.1 命令セットの特徴
命令セットの特徴を理解し、それを活かしたプログラムを設計するか否かは、並のプログラマと優れたプログラマとの分岐点の一つになります。
5.1.1 変更困難性
仕様を公開した後では命令セットの変更は困難です。命令語の追加は可能ですが、既存の命令語の仕様の変更や削除はできません。既に開発されたプログラムが動かなくなるからです。このため、設計段階で適用範囲や将来動向などを慎重に考えて仕様をまとめねばなりません。
5.1.2 抽象化と微細化
(1) 各命令語がもつ機能の抽象化と微細化は、コンピュータを広範な用途に適用するために不可欠です。特定の業務に直接対応するような機能は、他の業務では使わない可能性が高いからです。
(2) 命令語の機能が微細で抽象化されるなら、操作対象のデータも微細で抽象化されてなければなりません。両者は対であり切り離しは不可能なのです。
(3) コンピュータのプログラミングでは、微細な抽象化された機能作用子(機械命令語)と情報部品(データ)の対を組み合わせ、社会が必要とする実務を実現することになります。
5.1.3 採用不可能な特性
(1) 不定長の対象
長さが固定でないデータは機械命令語で扱うのが困難です。不可能ではありませんがコンピュータの機能や動作が複雑になります。
(a) 代表的な例に文字列データがあります。
(b) 10進数表現のデータも同様です。
(c) 命令語の長さも固定長の方が好まれます。
(2) 複雑さへの対処
原則は単純さの追求です。機能や構成の複雑な事物は原則として採用しません。敢えて採用する場合は、それにより大きな利益が期待できるほか、蒙る不利益が許容できる場合に限られます。
5.2 機械命令語の表現形式
命令語の表現形式を軽視してはなりません。単なる外見や形式ではありません。機械命令語の骨格を決めてしまうので、機能もその骨格が許す範囲に限られてしまうのです。
(1) 指導原理
表現形式の設計における指導原理は、表現対象を少なくすることと、それぞれの対象に含まれる要素の数を少なくすることです。命令語の語長を短くするためだけでなく、命令コードを解読する機構の肥大化を防ぐためです。究極の例は対象数も対象内の要素数も1つの場合です。一方のデータはスタック上に置き、他方のデータは主記憶中に置く場合はこれに相当します。この場合の命令語の形式は、「命令コード 主記憶のアドレス指定」のようになります。
(2) 前提
演算操作の対象を2つに絞ります。いわゆる2項演算です。例えば“a + b + c“の演算は、”d = a + b“ と ”d + c“の演算命令に分けるのです。
(3) 演算対象の種類
演算対象のデータの存在場所を、レジスタ、主記憶域、命令語中のデータ(即値といいます)にするのが一般的ですが、スタック上のデータを含める場合もあります。この場合、①レジスタとレジスタ、②レジスタと主記憶中のデータ、③レジスタと即値、④主記憶中のデータと主記憶中のデータ、⑤レジスタとスタックの各場合が考えられます。どこまでを含めるかは命令セットの設計者の判断に委ねられます。なお、④は汎用コンピュータやマイクロコンピュータに採用例があります。いずれも転送量が可変のデータ移動を伴う命令です。この場合は2組のアドレス情報とデータ転送量を何らかの方法で指定しなければなりません。
(4) 実例
本稿では紙幅の関係で多くは説明できません。そこで標準的な例をやや詳しく説明します。図3は1960年代中葉以来使われ続けているコンピュータの基本的な命令形式です。データの一方はレジスタに、他方は主記憶域にある場合です。レジスタは番号(名前)で指定します。主記憶域のデータは、データ群の起点を起点レジスタ(BR)で指定し、何番目の組かを指標レジスタ(XR)で指定し、組中の位置は変位Dで指定します。図4はこの指定方式の例です。4組のメンバーからなる構造体配列のうち、右端のメンバーを指定する場合は図示のように指定します。BRとDは固定の値になりますが、XRの内容を変化させることにより指定する番地は変得られます。このような指定方法を指標レジスタ修飾といいます。
5.3 機械命令語のデータ処理機能
命令語のデータ処理機能を充実させるほどコンピュータの開発費は増えます。回路が増えることからコンピュータの価格も高くなります。逆に機能を削るとコンピュータは安価になりますが、プログラマへの負担が大きくなる可能性が高まります。切り分けの境界をどこに設定するかは困難な決断です。
5.3.1 前提
命令語の機能の設計とは、操作内容とその対象を決定することです。操作対象は2つに限られます。命令語の表現形式からくる制約でした。“操作”と“その対象”とは不可分の関係です。操作対象はデータ型とも呼ばれます。
5.3.2 指導原理
命令語の設計における暗黙の指導原理を紹介します。
(1) 抽象化
コンピュータの汎用性を高めるため、操作も操作対象も抽象化します。特定のアプリケーションのためだけの機能をもつ命令語は設けません。
(2) 単純な機能の追求
単純な機能の命令に限定します。ひとつでも複雑な命令を認めると命令実行機構が複雑になるほか、命令の実行性能が落ちる可能性があるからです。複雑な機能は単純な命令を組み合わせたサブルーチンとして実現します。
5.3.3 命令の機能の例
一般的な機械命令語の機能について説明します。
(1) 四則演算
整数型と実数型のデータを対象とした加減乗除の命令群があります。整数型のデータでは符号付整数と符号なし整数(論理数)の加減乗除が考えられます。10進数の演算命令をもつコンピュータもあります。
(2) シフト演算
シフトとは桁移動のことです。通常、シフト数は任意に指定できます。シフト方向が左と右のシフト命令があります。シフトの仕方には、符号付き整数と、符号のない論理数を想定したシフト命令とがあります。両者はシフトの仕方が異なります。頭部と尾部を連結してシフトする回転命令を持つ例もあります。
(3) ブール代数演算
論理積、論理和、否定、排他的論理和などのブール代数演算命令です。この演算のための特定のデータ型はありません。
(4) データ転送
レジスタと主記憶域との間のデータ転送のほか、レジスタ間の転送、実効アドレス値のレジスタへの設定、即値データのレジスタへの設定、スタックとレジスタ間のデータ転送などの命令が考えられます。
(5) 命令実行流の制御
条件分岐命令、サブルーチンコール命令、ループ制御命令などが主要な命令です。
(6) 入出力命令
入出力装置を動作させるための命令です。携帯電話などでは各種のセンサー、通信機構、カメラ、ディスプレーなどが入出力装置です。
(7) システム管理命令
OSのカーネル部分のみが使える命令群が必要です。システムの動作環境を維持し制御するために使います。
5.3.4 命令実行モデルの例
図5を用いて機械命令語の実行過程を説明します。既に説明しましたが、機械命令語が実行されるプロセスを、機能の点から命令語の読み出し、解読、データの準備、演算、結果の格納の5段階に分けます。
(1) 命令語の読み出し
プログラムカウンタの値を使って命令キャッシュから命令語を読み出します。キャッシュに無い時は主記憶域から参照アドレスに相当する記憶ブロックをキャッシュに転送します。その間の適当なタイミングで必要な命令語を取出します。
(2) 命令語の解読
読み出した命令語を解読します。命令語の解読により命令語長もわかるのでプログラムカウンタの更新も行えます。
(3) データの準備
2組のデータを準備します。主記憶域のデータの場合は実効アドレスを計算してからデータキャッシュを調べ、あればそこから読み出し、なければ主記憶域からキャッシュへ転送します。
(4) 演算実行
データが揃ったら命令語で指定された演算器を使って演算をします。図5では、整数演算、実数演算、ブール代数演算、シフト演算などの演算機構が示されています。
(5) 結果の格納
演算した結果をレジスタまたは主記憶へ書き込みます。主記憶域の場合は、キャッシュに登録されていればキャッシュに書き、キャッシュになければ主記憶からブロック転送をした後に結果をキャッシュに書きます。この書き方をストイン方式と言います。書き込みは必ず主記憶に対して行うストアスルー方式もあります。
6. まとめ
コンピュータに関する基本的な知識は優れたプログラマになるためには不可欠です。このような認識のもとに、本稿では機械命令セットの設計思想を中心に解説しました。以下に挙げる事項はプログラマを志望する人への大切な示唆です。
(1) 機械命令語は小さな働きをする微小能動情報部品と言うことができます。大きな機能のプログラムを作るには、多数の微小能動情報部品(機械命令語)を根気よく着実に組み合わせていかねばなりません。
(2) 機械命令語の操作対象であるデータも抽象化された微小受動情報部品です。プログラマは微小受動情報部品に微小能動情報部品を結合する行為を積み重ねることで、大きなプログラムを作り上げるのです。この知的作業を着実に成遂できる人のみがプログラマとして成功するのです。
(3) 現実世界の情報を微小受動部品に抽象化する能力が必要です。
計画中の2編の続編、(仮称)“データの表現と操作編”、(仮称)“プログラム要素編”を合わせて理解することにより、プログラミングのための基礎力が得られると思います。
YAMAMOTO
記事がいいねと思ったらシェア、またはブログ村クリックで応援お願いします!にほんブログ村