備忘録とか日常とか

学んだこととかを書きます。

「プログラムはなぜ動くのか」を読んだ

朝出社したら自分のデスクにおもむろに置いてあったので読んだ。

プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識

プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識

この「なぜ」シリーズは2001年から刊行されており、他にも「コンピュータはなぜ動くのか」「ネットワークはなぜつながるのか」等の書籍がある。
昔から入門とか情報工学の基礎知識を身に着けるために読まれている本らしい。

ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識

ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識



ちなみに「プログラムはなぜ動くのか」第二版の1刷は2007年なので、内容としてはかなり古い。メモリ512MBとかの時代。江戸時代かっつの。。
それでもアセンブリの基礎に触れる機会など、かなり限られた業種やニッチな趣味でもしてない限りないと思われるので勉強にはなった。ハード寄りな部分の挙動は昔から劇的に変化することもなさそうなので、多少古くても問題ないのかもしれない。

以下各章の内容とひとこと要約・感想。

1. プログラマにとってCPUとは何か

CPU内の大まかな構造とレジスタについての説明。
種々のレジスタがそれぞれどのような役割を果たし、条件分岐、繰り返し、関数呼び出し等がどのように実現されているかを簡単に解説している。突き詰めればCPUは非常に単純な処理しか行っていない、らしい。

2. データを2進数でイメージしよう

コンピュータは2進数ですべてを扱っており、そのほうが都合がいい理由などのお話。
情報系の分野に疎い人のための易しめな解説。

3. コンピュータが小数点数の計算を間違える理由

引き続き2進数の話、浮動小数点がどう表現するかなど。
情報系の分野に(略)

4. 四角いメモリを丸く使う

メモリを使ってどのようにデータを表現するか、というお話。
char, int, longのメモリ確保みたいなところから、配列の実現方法(スタック、キュー、リスト、2分木探索)等の説明。メモリーICの物理的な仕組みみたいなところも。pushとかpopとかqueueとか待ち行列とか、情報工学の基本用語なんかも解説してくれて情報量は多い。

C言語初学者はこの章を読むとポインタやメモリに関する理解が深まると思う。

5. メモリーとディスクの親密な関係

モリーに対して、ディスクはどのような役割を担うかみたいな話。
ディスク上のデータはメモリに一度格納されてからしか使えないという原則から、キャッシュ、仮想記憶(ページング方式・セグメント方式)、DLL、スタティックリンク、ディスクの物理構造(セクタ単位で扱われる)など。

中でも_stdcall呼び出しというのは初めて知った。

スタックはさまざまな場面で再利用されるメモリー領域なので、使い終わったら元の状態に戻す処理が必要になります。

このスタックのクリーンアップ処理を、何度も呼び出される関数の側で行うようにすれば、呼び出す側で行う場合よりもプログラム全体のサイズを小さくできます。

通常mainで呼び出した関数のクリーンアップ処理は呼び出し側で行われるため、何回も同じ関数を呼び出すとその分だけクリーンアップ処理部分のコードが冗長になる。じゃあ関数側に処理を書いたら節約になるじゃん、ということらしい。

計算資源の制約が厳しかった時代の涙ぐましい努力が伺えて面白かった。今でも組み込みとかでは使うのか…?
どちらかというとコンパイラとか作る人のための知識な気がする。

6. 自分でデータを圧縮してみよう

急に毛色が変わって圧縮の話。
ランレングス法、ハフマン法のアイディアから基本アルゴリズムの説明と、可逆・非可逆圧縮等の説明。
普段使っているzipのLHA圧縮がハフマン法の応用だと初めて知った。こういうの思いつける人は天才だと思う。

7. プログラムはどんな環境で動くのか

OSの偉大さを説く話。
APIを提供してくれることでハードに依存しないプログラムを作成できるということを、歴史的経緯と一緒に説明してくれる。MS-DOS時代って大変だったんだね。

さらにJava仮想マシンBIOSについても少し触れてる。Javaコンパイルバイトコード生成→OS毎のJava仮想マシン→ネイティブコードという流れでOSの違いを吸収する、とか。
ブートローダの語源がまじのブーツだったとは思わなかった。

8. ソース・ファイルから実行可能ファイルができるまで

コンパイラによって実行可能ファイルができるまでの流れの話。
ソースをコンパイルして.objファイルができ、スタートアップやライブラリからも.objを引っ張ってきてリンクして出来上がり。
実行時にDLL呼び出して使うとか。

再配置情報、スタック、ヒープなんかもこの章で解説がある。

9. OSとアプリケーションの関係

ハードを意識せずプログラムを作成できるのはOSのおかげだよ、という話。
また、Windows OSの基本機能(マルチタスクとかデバイスドライバの自動設定とか)についてちょっとだけ説明。

10. アセンブリ言語からプログラムの本当の姿を知る

Cのソースとアセンブリを見比べて、CPUが実際はどのような挙動をしているのかを見る話。この本で最も内容が濃い章かもしれない。
1章でさらっと触れた分岐や関数呼び出しの仕組みを、アセンブリ言語を追いかけながら実際に理解を深めることを目的としており、勉強になる。

研修で実際のアセンブリ(といっても超単純なプログラムだが)を見る機会はあったが、意味不明すぎて結局ちゃんと見ずにCのソースしかいじってなかった。
もう少し早く読んでおけば学ぶこともあったかもしれない。

11. ハードウェアを制御する方法

CPUやメモリと違い、外部接続のハードウェアがどのように制御されているかという話。
IN、OUT命令とポートを使ってデータのI/Oを実現している。加えて、割り込み処理やDMA(Direct Memory Access)などを解説。
組み込みの基本みたいなとこか。

12. コンピュータに「考え」させるためには

プログラムに人間的な考えや勘を盛り込んでみよう、というお話。(この章は若干の蛇足感がある…)
じゃんけんプログラムをつくるのだが、括弧つきで書いてるように、実際に考えてるわけでない。あくまで「それっぽく」動くようにするために経験に基づいてif-thenルールをひたすら盛り込んでいる。

今のAI時代に下手に「コンピュータが考える」とか「知能を実装する」とか言っちゃうと、「知能とは何か」みたいな話まで行ってしまうので、まあ昔の本ということでご愛敬である。

終わりに

教養として知っておいて損はない内容が多かった。
アセンブリ言語に興味を持つ入り口にはなるかもしれない。自分はちょっとしんどいので無理ですごめんなさい。
入門書的な扱いだが、全くIT知識のない人が読むには少々つらいかもしれない。
大学一年の電気・情報系学部の教養の授業とかで扱うといいんじゃないかな。と思いました。