プログラムはなぜ動くのか 第2版
https://images-na.ssl-images-amazon.com/images/I/513mo%2Byq4WL._SX350_BO1,204,203,200_.jpg
概要
内容
プログラムはなぜ動くのか』6年ぶり、待望の改訂第2版!
プログラムがコンピュータの中でどのように動作するのかを、誰にでもわかるように説明しました。プログラムは、メモリーにロードされ、CPUによって解釈・実行されます。その仕組みを、多数の図を使って、順序だてて解説していきます。
第2版では、第1版で特に関心の高かったプログラムがメモリーをどう利用しているかについて、より丁寧な説明を加えたほか、多くの注釈を入れました。また、サンプル・プログラムを、第1版のVisual Basicからプログラムの動きが見えやすいC言語に統一し、巻末にC言語の構文を説明した補章を追加しました。初級者、中級者の人、どちらにもお勧めです。
特徴1:CPU、メモリー、プログラムの動作環境など・・基礎からきちんと解説!
CPU(プロセサ)はどうやってプログラムを動かしているの? CPUとメモリーの関係は? どうやってディスプレイに表示されるの? など基礎的な部分からきちんと説明しています。
特徴2:メモリーについて充実した説明!
第1版でなんといっても多かったのが「プログラムがメモリーをどう使っているのかがわかって、自分のプログラムの動きがわかった!」という声でした。第2版では、メモリーの使い方についての説明を強化しました。関数や変数、ポインタや配列は、どうメモリー領域を使っているのかをぜひ知ってください。
特徴3:Windowsの仕組みわかる!
プログラムの動く仕組みを知るとは、Windowsの仕組みを知ることにもつながります。フリーソフトをインストールしたときに出会うDLLファイルや、EXEファイルは、その実体は何だろう、と感じるパソコンユーザーも多いはずです。本書は、プログラミング本ではありません。豊富な図表を使って、その仕組みや流れが感覚的にとらえられるようにしています。
著者
矢沢 久雄
1961年栃木県足利市生まれ。株式会社ヤザワ代表取締役社長。グレープシティ株式会社アドバイザリースタッフ。電脳ライター友の会会長兼事務局長。大手電気メーカーでパソコンの製造、ソフトハウスでプログラマを経験し、現在は独立して、パッケージソフトの開発と販売に従事している。本業のかたわら、プログラミングに関する書籍や雑誌記事の執筆活動、大学やIT企業における講演活動なども精力的に行っている。
第1章 プログラマにとってCPUとはなにか
CPUの中身を覗いてみよう
CPU:最終的にマシン語となったプログラムの内容を解釈して実行する装置で、以下の4つから構成
レジスタ:処理対象となる命令やデータを格納する領域(一種のメモリーみたいなもの)
制御装置:メモリー上の命令やデータをレジスタに読み出し、命令の実行結果に応じてコンピュータ全体を制御
演算装置:メモリーからレジスタに読み出されたデータを演算する役目をもつ
クロック:CPUが動作するタイミングとなるクロック信号(GHz)を発生させる
メモリー:通常メインメモリーのことで、ここに命令とデータを格納する。PCの電源を切ると命令やデータは消える。
1バイトごとにアドレスという番号が振られていて、CPUはこのアドレスを指定してデータの読み書きを行う
プログラムが実行される流れ
プログラムが動き出すと、クロック信号に合わせて制御装置がメモリーから命令やデータを読み込む
命令を解釈・実行することで演算装置でデータが演算される
演算結果に応じて制御装置がコンピュータを動かす(制御≒演算以外の処理のこと)
CPUはレジスタの集合体
https://slidesplayer.net/slide/11602199/62/images/13/%E4%B8%BB%E3%81%AA%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF%E3%81%AE%E7%A8%AE%E9%A1%9E%E3%81%A8%E3%81%9D%E3%81%AE%E5%BD%B9%E5%89%B2+%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF%E3%81%AE%E7%A8%AE%E9%A1%9E+%E5%BD%B9%E5%89%B2+%E3%82%A2%E3%82%AD%E3%83%A5%E3%83%A0%E3%83%AC%E3%83%BC%E3%82%BF+%E6%BC%94%E7%AE%97%E3%82%92%E8%A1%8C%E3%81%86%E3%83%87%E3%83%BC%E3%82%BF%E5%8F%8A%E3%81%B3%E6%BC%94%E7%AE%97%E5%BE%8C%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E6%A0%BC%E7%B4%8D%E3%81%99%E3%82%8B%E3%80%82+%E3%83%95%E3%83%A9%E3%82%B0%E3%83%BB%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF.jpg
先程のCPUの4つの要素の中で、プログラマが意識しなけれなならないのはレジスタだけ
プログラムはレジスタを対象として記述されるから
アセンブリ言語:本来は電気信号であるマシン語の命令に、動作を表す英語の略語(ニーモニック)を割り当てたもの
アセンブリ言語とマシン語は、基本的に1対1で対応している
アセンブル:アセンブリ言語→マシン語への変換のこと
逆アセンブル:マシン語→アセンブリ言語への変換のこと
CPUの制御装置は、プログタムカウンタの値を参照して実行の流れを追っている
フラグレジスタ:直前に実行した演算の結果、アキュムレータの値が負、ゼロ、正のいずれになったかを記憶する
関数呼び出しの仕組み
コール命令:関数の入口のアドレスをプログラムカウンタに設定する前に、次に実行する命令のアドレスをスタックに保存
スタック:メインメモリー上の領域のこと
リターン命令:スタックに保存されたアドレスをプログラム・カウンタに設定する機能を持つ
第2章 データを2進数でイメージしよう
コンピュータが情報を2進数で扱う理由
IC:集積回路と呼ばれる電子部品ことで、コンピュータの内部はICによって構成されている
ICにはピンが剣山のように並んでいるが、ICのピンは0Vか+5Vの2つの状態しか表せない
この性質から、コンピュータでは必然的に情報を2進数で取り扱わなければならないことになる
論理演算をマスターするコツ
算術演算:加減乗除の四則演算のこと
論理演算:2進数の各桁の0と1を個別に扱う算術のことで、以下の4通りが存在する
論理否定(NOT):0を1に、1を0に反転すること
論理積(AND):両者が1の場合に演算結果が1に、それ以外は演算結果が0になる
論理和(OR):少なくともどちらかが1の場合に演算結果が1に、それ以外は演算結果が0になる
排他的論理和(XOR):両者が異なる値の場合に演算結果が1に、それ以外は演算結果が0になる
第3章 コンピュータが少数点数の計算を間違える理由
コンピュータが計算を間違える理由
間違う理由:10進数の小数点数の中には、2進数に正確に変換できないものがあるから
循環小数など正確に表せない値は、近似値になってしまう
コンピュータの計算間違いを回避するためには
計算間違いを回避する方法は2つほどある
間違いを無視すること
小数点数を整数に置き換えて計算すること(整数の計算はコンピュータは間違わない)
第4章 四角いメモリーを丸く使う
ポインタなんてかんたんだ
ポインタ:データの値そのものではなく、データが格納されているメモリーのアドレスを持つ変数のこと
ポインタを使うと、任意のアドレスを指定してデータの読み書きが可能になる
データ型とは、ポインタに格納されたアドレスから一度に何バイトのデータを読み書きするかを示すもの
スタックとキュー、さらにリング・バッファ
スタックとキューは、どちらもアドレスやインデックスを指定せずに配列の要素を読み書きできるもの
スタック:LIFO(後入れ先出し)でデータを出し入れする
キュー:FIFO(先入れ先出し)でデータを出し入れする
あらかじめメモリー内にスタックやキューのための領域を確保し、書き込みや読み出しの順序を決める
これによって、アドレスやインデックスの指定が不要になる
リング・バッファ:キューの一般的な形態の一つで、配列の末尾の次を配列の先頭と位置づける形のこと
リストは要素の追加や削除が容易
リスト:配列の個々の要素にデータの値だけでなく次の要素のインデックスも付加することで実現するもの
これにより、数珠つながりのリストになり、要素の追加や削除に時間がかからなくなる
2分探索木:リストを工夫し、配列に要素を追加するときに大小関係を考慮して左右2つの方向に分岐させるもの
要素を追加するときに、あらかじめ格納されている値より大きければ右に、小さければ左に格納する
個々の要素に、データの値と2つのインデックス情報を持たせることで実現する
データの探索がとても効率的に行えることがメリット
第5章 メモリーとディスクの親密な関係
ディスクアクセスを高速化する「ディスク・キャッシュ」
ディスクキャッシュ:一度ディスクから読み出されたデータを保存しておくメモリー内の領域のこと
次に同じデータが読み出されるときは、ディスクではなくディスクキャッシュの内容を読み出す
現在ではハードディスクのアクセス速度が向上したため、ディスクキャッシュはそれほど大きな効果を上げなくなった
第6章 自分でデータを圧縮してみよう
第7章 プログラムはどんな環境で動くのか
どこでも同じ実行環境を提供するJava仮想マシン
Javaには、「プログラミング言語としてのJava」と「プログラムの実行環境としてのJava」の2つの側面がある
Javaは他の言語と同じように、Javaの文法で記述されたソースコードをコンパイルして実行する
コンパイル後に生成されるのはバイトコードで、特定のCPU用のコードではない
この生成したバイトコードの実行環境をJava 仮想マシン(VM)と呼ぶ
Java VMはJavaバイトコードを逐次ネイティブ・コードに変換しながらプログラムを実行する
ブラウザのキャッシュも同じ理論で画像の読み込みなどを高速化している
ディスクをメモリーの一部として使う「仮想記憶」」
仮想記憶とは、ディスクの一部を仮想的にメモリーとして使うもの
仮想記憶によって、メモリーが不足している状態でもプログラムの実行が可能になる
仮想記憶と言っても、実際に実行されるプログラムはその時点でメモリー上に存在しなければならない
CPUはメモリーにロードされたプログラムしか実行できない、という部分は変わらないため
仮想記憶を実現するために、実際のメモリーの内容と仮想メモリーの内容を置き換えながらプログラムを実行している
実際のメモリーを「実メモリー」「物理メモリー」と呼ぶ
Windowsでは、ページング方式といって、ページ単位に分割して置き換えをすることで仮想記憶を実現している
第8章 ソース・ファイルから実行可能ファイルができるまで
コンピュータはネイティブコードしか実行できない
ネイティブ・コード:CPUが解釈・実行できる形式のプログラムのこと
ダンプ:ファイルの内容を1バイトずつ2桁の16進数で表示すること
ソースコードを翻訳するのがコンパイラ
コンパイラ:C言語などの高水準言語で記述されたコードをネイティブコードに翻訳する機能を持ったプログラムのこと
コンパイラは、コードを記述する言語の種類に応じて専用のものが必要になる
読み込んだコードの字句解析や構文解析を経て、ネイティブコードに変換する
コンパイラだけでは実行可能ファイルが得られない
ネイティブコードのファイルはそのままでは実行できない
コンパイルしたファイルに「リンク」の処理を行って、実行可能なEXEファイルを得る
コンパイル後には、.obj拡張子の「オブジェクトファイル」が実行される
複数のオブジェクトファイルを結合して、ひとつのEXEファイルを生成するのがリンク
リンクを行うプログラムのことをリンカーとよぶ
ロード時に作られるスタックとヒープ
プログラムがロードされたメモリー領域には、スタックとヒープという領域が作られる
スタック:関数の内部で一時的に使用される変数(ローカル変数など)や引数を格納するためのメモリー領域
ヒープ:プログラムの実行時に任意のデータやオブジェクトを格納するためのメモリー領域
EXEファイルをメモリーにロードして実行した時点で、スタックとヒープのためのメモリー領域が確保される
スタックとヒープは、メモリーの使い方が少し異なる
スタックにデータの格納と破棄を行うコードは、コンパイラで自動で生成されプログラマが意識する必要はない
ヒープのためのメモリー領域は、プログラマが明示的にプログラムを記述し確保と開放を行う必要がある
メモリ・リーク:ヒープを解放し忘れ、処理の終了後もメモリー領域が確保され メモリー不足に陥ること
高度なQ&A
コンパイラとインタプリタの違い
コンパイラは実行前にソースコード全体を解釈し実行する
インタプリタは、実行時にソースコードの内容を1行ずつ解釈して処理する
分割コンパイルとは
プログラム全体を複数のソースに分けて記述し別々にコンパイル、最後に1つのEXEファイルにリンクすること
ひとつひとつのソースコードが短くなるので、プログラムを管理しやすくなる
ビルドとは
コンパイルとリンクを続けて行うこと
ガベージコレクションとは
処理が終わって不要になったヒープ領域のデータやオブジェクトを破棄して、メモリー領域を解放すること
第9章 OSとアプリケーションの関係
システム・コールと高水準言語の移植性
OSのハードウェア制御機能は、小さな関数の集合体として提供されている
これらの関数および関数を呼び出す行為のことをシステム・コールと呼ぶ
高水準言語では、独自の関数を使ってコンパイル時に該当するOSのシステムコールが呼ばれる仕組みになっている
要するに、ハードウェアごとの独自実装部分が抽象化されているteru.icon
システムコールによって、プログラマーはハードウェアを直接制御するプログラムを記述しなくてよくなる
第10章 アセンブリ言語からプログラムの本当の姿を知る
第11章 ハードウェアを制御する方法
ハードウェアの入出力を支えるのはIN命令とOUT命令
IN命令:指定したポート番号のポートからデータを入力し、それをCPU内部のレジスタに格納する
OUT命令:CPUのレジスタに格納されているデータを、指定したポート番号のポートに出力する
第12章 コンピュータに「考え」させるためには