第三世代OSASKの仮想CPUの仕様(2)
- (by K, 2013.03.09)
- (osask.netに書こうと思ったんだけどパスワードを忘れて新規ページが作れない。メモを見つけるまでこっちに書いておく)
- 今回はメモリアクセスに関する話に限定
- これは結構重要なので、たくさん書くことがある。
- そしてCLEとの違いが大きいのもここかもしれない。
基本的な仕組み
- アドレスレジスタは、必ずなんらかの構造体のポインタが入る(もしくはNULL)。プログラム上ではそれは一時的に void * でキャストされてそのように扱われるかもしれないけど、それとは無関係にアドレスレジスタのさす先は、何らかの構造体がなければいけない。
- ポインタのキャストは認めるが、メモリ上に展開されている構造体とマッチしないようなキャストは許さない。
- これらを言語レベルではなく、仮想機械語レベルで保証する。
- mallocの際には構造体を指定しなければならず、メモリ確保成功の場合、それはOS側にも登録される。つまりmallocは領域のサイズだけではなく、領域の構造体情報も含めて記録している。
- この構造体情報があるからこそ、ポインタのキャストが不整合になっていないかを確実に調べられる。
- 配列アクセスについてはデフォルトではバウンドチェックが毎回入る。
- 32bitのint域を8bitの char [4] でキャストしてアクセスするなどの方法は全て例外になる。それがやりたいのなら32bitのintをレジスタにロードして、シフトでしかるべき値を得るべきである。
- これによってエンディアンに依存しなくなる。
- 逆に char [] に対して、intでアクセスして4倍速にする技も使えない。
- そういう方法で高速化したいのなら「ネイティブコード混在」で好きなようにすればいい。性能よりもエンディアンに依存しないことを重視するのでここは譲れない。