Kの開発メモ #0002
- (by K, 2013.03.26)
- ここは川合の開発の進捗などをレポートするところです。
- 当初はその予定だったが、今ではむしろ主たる目的はKの備忘録になってしまっている(苦笑)。
2013.03.26 Tue
- DIFFPTRやCOMPPEなどを追加。ついでに裏APIの仕様も少し変更してリビジョン0003へ。
- 2013.03.19(Tue)から実装を開始したので、これで1週間経ったことになる。結構はかどった。しかし疲れた。体重も1kgくらい減った。これは長くは続けられないと思う。
- よくよく考えた末、軽量の関数呼び出しと重量の関数呼び出しの二種類が必要かなと思う。軽量callはセキュリティ的に防御せずに分岐。重量callはがっちり守る。リターン命令以外では帰ってこれない。
- もう少し見栄えがするものが作れるようになったら、ソースとバイナリを分離してもう少しきれいなパッケージにするべきだよな・・・。現状のままでは「お客さん」がとっつきにくすぎる。
2013.03.27 Wed
- 裏APIに余興でほんの少しだけグラフィック機能をつけてみた(Windows限定)。osecpu.exeは7.50KBになってしまった。とりあえずapp0006a.oseというアプリを作ってみたところ、ちゃんと表示できているようだ。
- 軽量callがほしくなったので実装中。・・・よしできた!
- アセンブラを必死に書いていると、結構疲れる。うーん、若いときにアセンブラでがんばったときはもっと疲れずにできたんだけどなあ。
- でもここでがんばっておけば、将来にわたって使えるわけなので(osecpuさえ移植すればx86が主流じゃない未来が来ても大丈夫、という意味)、がんばる気にはなる。
2013.03.28 Thu
- 裏APIの呼び出し方法が、うさんくさい隠し命令ではなくて、普通の軽量callでできるようになりました。
- ラベル番号の管理でやってられなくなったので、ローカルなラベル番号をうまい具合につけてくれるプログラムを書きました。
- 150行ほどのC言語プログラムです。
- これもいつかOSECPUで書き直したいです。
- そのほかいろいろ調整して、OSECPUのアセンブラが第三世代OSASKと互換になりました。これでやる気は百倍です。だって何を書いても、将来にわたってずっと使える(と信じられる)からです。
- 本日の成果:
2013.03.29 Fri
- (1) lbstk01にバージョンアップしました。→page0017
- (2) 多少の癖はあるものの、とにかくかなり書きやすくなったと思う。
- 思い起こせば、最初はDBしか使えなかった。
- これに対してプリプロセッサを使うことで、基本的な命令は使えるようになった。
- さらに#defineを増やして、CMPJNEなどの便利な複合命令も作った。
- そしてlbstk01みたいな超簡易なプログラムを組み合わせることで、手動によるラベル管理は激減し、構造化言語みたいになってきた。
- このように徐々にステップアップできるのはとても有効だと思う。プリプロセッサのおかげだろう。
- 今後、プリプロセッサをOSECPUアプリとして書きなおす日が来るだろう。プリプロセッサくらいならきっと書ける。
- lbstk01もOSECPUアプリに移植できるだろう。そうなれば、今後は小さなosecpu.exeだけを多数のCPU向けに書き直すだけで、アプリ開発環境もすぐに使えるということを意味する。
- (3) ここまで来るのに10日しかたってない。・・・そしてここまでの技術はどれもとても平凡で、なんとなれば10年前にだって十分に開発できた内容だと思う。それなのにすごく有効そうに思える。
- 今まで僕は何をやっていたんだと強く思う。これがあればCPUの仕様とは無関係に自由にプログラムが書けるじゃないか。しかも大して遅くはならない。
- 今まで少ないレジスタで必死にやりくりしていたのが情けない。
- OSECPUにはやがて正規のAPIをつけ始めると思うけど、そのAPIは原始的なI/Oに限られるだろう。つまり全然使いやすくはない。使いやすいAPIはその原始的なAPIをラップすることで用意する。もちろんそのコードはOSECPUで書かれる。
- そうすれば、osecpu.exeはシンプルなままだ。移植は簡単だ。なんというか、osecpu.exeはドライバを含んでいるといってもいい。つまり「原始的なI/OのAPI」=「ドライバ」というわけだ。
- このスタイルになっていれば、WindowsでもLinuxでも「はりぼてOS」でも、TownsOSでもMacOSでもゲームボーイアドバンスでも、すべての32bit環境で共通のアプリ実行基盤が提供できたはずだ。
- しかもそれはJavaなどとは違って非常に軽量で、osecpu.exeは30KBとかその程度なのだ。なんていい世界だろう。・・・おっと忘れていた、しかもセキュアだ。
- しかも第三世代OSASKの仕様も盛り込めば、仮想CPUはついに32bitという制限もなくなり、実際のCPUのビット数とは無関係に自由なbit数でアプリを記述できるようになる。
- つまり64bitマシンで16bitアプリを動かすことができるし、16bitマシンで64bitアプリを動かすこともできるようになる。
- これは必要に応じて多倍長演算を利用することで実現する。
- OSECPUでは、どんなCPUにでも対応できるように用心深く設計してある。
- たとえばページングを持たないCPUがある。そんなCPUに対してでも、メモリアクセス命令は4命令しかないので、その命令のJITの際にページングに相当する動作のコードを付与して出力すれば、なんとページングがあるかのように動作することができる。
- 同様に、キャッシュメモリがなくて、単に一部のRAMだけが高速にアクセスできる、なんていう場合も、JITCでキャッシュ管理のコードをつけて出力すれば問題ない。
- レジスタが少ないCPUに対してはメモリで代用させればいい(x86版はまさにそうなっている)。
- CPUにハードウェア割り込みの機能がなくても、数命令おきに割り込みをチェックする命令をはさめば、割り込み機能をソフトウェアで提供することもできる。
- こうして考えていくと、実際のCPUに必要な機能は本当に少ない。セグメンテーションもページングもキャッシュコントローラも割り込み機構もいらない。例外もいらない(アクセス違反はすべて事前に検出されているから)。特権モードもいらない。過去のCPUとの互換性もいらない(どうせOSECPUのコードを動かすだけだから)。プロテクトモードもいらない。16bitモードとか32bitモードとか64bitモードとか切り替える必要もない。
- CPUはきっととてもシンプルにできるだろう。そうなれば速くなるだろう、安くなるだろう、消費電力が下がるだろう。いいことばかりだ。
- (4) OSECPUは第三世代OSASKの仕様を簡略化したもので、その第三世代OSASKは、ページングなどの仮想記憶支援機能を持たないCPUにどうやって仮想記憶を実現したらいいかというところから研究が始まった。
- それは結局、ポインタに細工をして、今はこのポインタ上のオブジェクトはスワップアウト中ですよというマークをつけるしかないという結論になった。メモリアクセスの際にはこのマークを見てからアクセスする。
- これを実現するために、ポインタレジスタは2つのポインタを持つことになった。一つは本来のポインタ。もう一つはマークのありかを指し示すポインタ。これによりマークは一つにまとまり、スワップアウトの際に変更するマークも一つで済む。
- こうなるとポインタレジスタは整数レジスタとはビット数が一致しなくなってしまう。それで汎用レジスタをやめることになった。
- メモリアクセスの際にはいくつかのチェックが入る(スワップアウトしていないかどうかとか)。セキュリティチェックがなくても。つまり遅い。それでメモリアクセスを減らす必要があると直感し、レジスタを増やした。こうして64+32レジスタ構成が生まれる。そしてこのおかげで、本当にメモリにおかなければいけないものだけがメモリにおかれるようになった(x86みたいなレジスタ数の少ないアーキテクチャでは、メモリにおくべきとかそういうのとは無関係に、レジスタ不足をメモリで解決している)。
- こういう背景が既にあり、その後セキュアなOSについて考えていたら、これはうってつけだと直感した。
- つまり何が言いたいのかといえば、セキュアにしようと思って考えた仕様ではなかったのに、気づいたらセキュア向きだったというわけだ。
- それでセキュア機能を少し追加して、そして簡略化のためにマルチビット対応に関する仕様を削り、OSECPUの仕様が出来上がった。
- こんなふうに本来の意図とは違う応用が可能な場合、僕は自分の設計の方針に確信を持つ(設計の際には少しでも汎用的でありたいと思っていて、予期せぬ応用が可能ということは汎用的である証だと思っているから)。
2013.04.01 Mon
- ADDやCMPcc命令で、即値が指定できたら便利だし速くなるかなと思ってそういう形式を追加してみたものの、速くなるどころかかえって遅くなる結果に。なんということだ・・・。
- 今日はセキュリティ関係のコードを書こうと思っていたのに、高速化だけで終わってしまった・・・。
2013.04.02 Tue
- OSECPUは当面の予定として、FPUをサポートしないし、MMXなどもサポートしないし、マルチスレッドもサポートしない。原始的な2Dのグラフィックはサポートするけど、ちょっとしたゲームを作る程度のことしか考えない。
- これは以下の理由による。
- この程度しかなくても相当に有用なものはいろいろ作れる。
- FPUやMMXやマルチスレッドが使える環境はそんなに多くはない。そのような環境に対してもOSECPUは有効であってほしい。だからまずは多くの機能を求めずに、多くの環境で共通にできることを増やしていく。
- やりつくしたら先へ進む、といった感じで。
- そもそもOSECPUのメインテーマはセキュリティなのであって、豊富な機能ではない。
- はじめはグラフィックもばっさり切り捨てようかとも思ったけど、それだとゲームが作りにくくなって遊べないかなと思い、それくらいはつけようと思った。
2013.04.03 Wed
- ついに3週目に突入。そろそろきりのいいところでペースを下げる準備をしなくては。
- 今日は体調があまりよくない。そろそろ限界か・・・。
- 現在、プログラムの中にデータを入れる方法について考え中。そろそろこれができてもいい時期なので。
- 会社の業務が忙しかったので、今日もリリースなし。
- データのうまい入れ方はすぐには思いつけそうにないので、とりあえず保留にして、アセンブラのマクロで抽象化しておく。それで試行錯誤しよう。
2013.04.04 Thu
- とりあえずデータは入った。現在サンプルアプリを作ってテスト中。あと1日あればできると思う。
2013.04.05 Thu
- サンプルアプリも動いた。サンプルアプリとしては一番大きい3759バイト。このうちの2000バイトはデータ。うーん、コード部分も結構大きい感じだなあ。まあ確かにいっぱい書いた気はする。手抜きでコピペばかりだけど。
- (app0010a.ose)
- じゃあ手抜きしない方法も考えるかな・・・。
- とりあえず改良。osecpu.exeがまだまだバカなので、このくらいが限界かなあ。
- バイナリ全体で2765バイト、このうちデータ部は2064バイト。まあ現状ではこんなものかな。
- (app0011a.ose)
- CLEだとコード部が半分以下になるんだろうなあ。
- (今夜アップロード予定)
- メモリアクセスをマシにした。現在サンプルアプリでテスト中。
- app0011a.oseは2623バイトに減った。
- (今夜アップロード予定)
- バイトコードリビジョンアップの基準。旧アプリが新osecpu.exeで誤動作する場合はリビジョンを上げる。エラーが出て止まるのが確実なら、面倒なのでリビジョンを上げない。新アプリが旧osecpu.exeで誤動作する場合もリビジョンは上げない。
こめんと欄