binary2.0

たとえばa.outやelf,PE/COFFの構造や、それがメモリ内でどうやって展開されて実行されるのかと言うことは本来どの辺で教えるべきものなんだろう?
a.outやelf,PEなんかの個々のフォーマット自体にはあんまり興味ないのですが、OSのローダがメモリにロードして仮想アドレスを割り当てたあとの動きは意識しておかないと危ないような。バスエラーがなぜ起きるのか、セグメンテーションとフォールトとは何か、スレッドとプロセスの違いは何か、とか。
あと、今時メモリマップを意識してプログラムを組むことってどれくらいあるんだろう。PS2PSPはメモリマップを気にする必要有ったけど、DSだとメモリマップ以前にコード領域の動的差し替えだのでいやでも気にしなくちゃならないかなー。メモリマップドI/Oはさすがに触らないものとしても(特権違反になる・・はず)PS2PS3みたいにリリース後にハードウェアが変わることもあるからなぁ。


プログラムを入門する際には、多くの場合WindowsLinux上で何かの言語を使ってHelloWorldから入るものとしても、高度なものが作れると言うことと、OSの構造や実行時のメモリ構造がわかるってのは直交する概念だからなー。
ScratchやEtoysみたいな簡易な環境や、なでしこみたいなわかりやすい環境(かたくなにクラスという概念を導入したがらなかったというのは関心に値する)から、OSレベルまで降りるにはどれくらいの壁があるんだろうなぁ。


私が教えている魔法学校の私の授業は「C言語は組み込み向け高級アセンブラである」というところを終始一貫貫いています。まずは文法から入るのは仕方ないにしても、大域変数と局所変数の話をするのに「パソコンの中で、プログラムはメモリを3つの領域に分けて動きます。text,data,stackの3つです」から入って、ポインタを説明するときには必ずポインタの16進表記をデバッガで見てから配列の話に入ります。これは、ゲーム機ってまだまだメモリマップを意識する必要有る・・という意識があるのですが、できればそんなところよりももっと高レベルな部分をやりたいのが本音のところ。
何より、こんな話をしたところで彼らが就職用の作品を企業に持って行って見せる際にはWindowsというかなり高度なOSの、DirectXというかなり層の厚いライブラリ越しにハードをたたいて作るので、何の役にも立たないんですよね。双方向リストやReallocによるコレクションの動的確保もSTLみたいなものを使っている限り意識することはないですし。そもそも、卒業生の約半分は携帯ゲームメーカーに入ってJavaObjective-Cでプログラムを組むことになりますからねぇ。実際のハードウェアはバラエティに富み、OSの介在すらも見えないところでゲームを作ることになります。
もちろん、私のようにバイトコードやクラスファイルの構造を意識しながらJavaでプログラムを組むこともできますが、多くの場合無駄な努力になりますし。製品のVMにそこまで低レベルなバグは滅多に残ってないので(ごくまれにあるけど)。
だいたい、今時の環境はCPUやメモリがどのように使われているのかを想像するのは難しいです。IPC1への長い道・・といったところで、複数段パイプラインと複数ある命令実行スロットのどこで何が行われているかを気にしながらプログラムを組むと、新機種が出たときにはまる羽目になりますし。SIMD命令への展開や、MIMD環境への自動移行なんかプログラマーが意識したら負けというか。


うーん、今は可能な限りPOSIXの上で教えてるけど、こんどからQEmu上で動くプログラムにしようかなー。QEmuでPRePのPowerPC標準ハードウェアって、動くよね? Arconでもいいや。EX68の方がいいかな(Human68Kがしょぼすぎるか)? VGAを直接たたいて文字を書く・・のは、無意味かなぁ。うーむ。