OSECPUのアプリはなぜ小さいのか
要点
- OSECPUのアプリが小さいのは、以下の理由によります。
- サポートしている命令数が少ない。
- 命令数が少なければ命令を表現するためのビット数が節約できます。いわゆる2バイト命令とかはありません。
- これはできることが少ないというよりも、余計なものがないと考えるほうが分かりやすいと思います。基本的な命令を組み合わせてプログラムを書いていくように設計されています。
- 基本単位が0.5バイト。
- 1バイト単位で考えていたら、どんなに短くても1命令で1バイトを使ってしまいます。パラメータがあったらそれだけで2バイト以上になってしまいます。
- 1バイトといったら0~255までが表現できるわけですが、正直なところそんなに多くの表現が必要なことは少なく、0~15で済む場合がほとんどです。ということで、基本単位を0.5バイト(4ビット)として、大きな数値を表現するときはそれを複数つないでエンコードしています(x86などでも1バイトに収まらないときは4バイトとかで書くのと同じことです)。
- 利用頻度の高い命令は短い。
- こういう機械語はよく使うと経験的に知っているので、それを生かしてよく使うものは短く書けるように工夫してあります。
- 命令長が可変長。
- OSECPUのコードはJITコンパイラによって翻訳されてから実行されるので、命令長が固定ではなくても全く問題ありません。規則正しければJITコンパイラが複雑になる心配もありません。
例を交えた解説
- R01レジスタに、定数3を代入。
213 : 1.5バイト
- R01レジスタに、定数0x1234を代入。
21741234 : 4.0バイト
- R11レジスタに、定数0を代入。
2910 : 2.0バイト
- 0x11というレジスタ番号は当然0.5バイトでは表現できないので、91という1.0バイト表現になっている(1.0バイトの値は0x80を加えて書くことになっている)。
- R02に1を加算する。
9421 : 2.0バイト
- 94が命令コード(0x14を意味して、ADD命令を指す)。
- [考察] x86の16bitモードと比較すれば、たとえば、レジスタに1を加算するのに2バイトも使うのは明らかに負けている(x86は1バイトで書ける)。2バイトの定数を代入するのに4バイトを必要とするのも明らかに負けている(x86は3バイトで書ける)。
- しかしその一方で、小さな値に限れば1.5バイトで代入できたり、命令長を0.5バイト長くするだけでレジスタを8本以上利用できるようになるなどのメリットもあり、結果的にはそのほうがプラスに働いている。それは結局利用頻度の問題である。プログラムでは0や1の代入は多く発生するが、それに対し0x1234を代入しなければいけないケースはまれである。したがってOSECPUはx86よりも勝つ機会が多く、トータルでも勝つことになる。
拡張性など
- OSECPUアプリの実行ファイルは、小さすぎて拡張性がないと思われるかもしれませんが、そんなことはありません。ちゃんと考えてあります。
- まず実行ファイルの最初の2バイトはシグネチャです。これでユーザの誤操作で実行ファイル以外を実行してしまうことを予防します。
- 次に3バイト目が以下の値の時には、特別な意味を持たせています。
- 0x(NOP):実行ファイルはバックエンドコードで記述されている
- 87(end-for):拡張ヘッダが後続する
- F0(NOPの別表現):tek5圧縮がかかっている
- アプリの先頭にどうしてもNOP命令を置きたいときは80で記述することになっています
- したがって、87から書き始めれば、スタックサイズやヒープサイズなど、必要な情報はちゃんと記述できます。MS-DOSの.COMファイルとは違うのです。
関連リンク
こめんと欄
- このページにこめんと欄はありません。このページの内容にコメントしたいときはimpressionsにお願いします。
|