次期バージョンで仕様変更を行います。
osecpu072dをベースにして、汎用コンテナを作ってみました。 差分は以下のページから見れます。
https://github.com/liva/osecpu/commit/5248115243915b1ee981491d49e0ec334ea42c1a
osecpu.cがSJISなもんで、コメントが文字化けしてます。コメントはファイルをダウンロードして確認して下さい。
さて、汎用コンテナって何ぞや?という話と、使い方を解説していきます。 (ちなみに、以下で出てくる「整数データ」とは、ポインタと区別するための用語です。)
今現在、OSECPUのmallocで確保したメモリ領域(配列)には、確保時に指定した型のデータしか代入できません。T_SINT32の配列にT_UINT16の整数データを突っ込む事は可能ですが、T_VPTRを突っ込む事ができません。要するに、一つの配列内にポインタと整数データをごちゃ混ぜにして突っ込む事ができないわけです。
この仕様は、普通にASKAでOSECPU開発をしている人にとっては別に苦にならないでしょう。でも、僕みたいなちょっと変わった事をやろうとする人間にとっては少し都合が悪いのです。
というわけで、ポインタも整数データも突っ込める配列、名づけて汎用コンテナを作れるようにしました。ポインタと整数データの二種類が突っ込めるだけなのに「汎用」とはどういう事だ!と言う人がいるかもしれません。でも、この汎用コンテナに突っ込めないデータは無いんですよ?凄く汎用的じゃないですか!
さて、使い方をグダグダと喋ってもアレなので、以下のコードを見てください。
#include "osecpu_ask.h"
junkApi_malloc(P02, T_VOID, 18);
LIMM(R00,0x8);
LIMM(R01,0x1);
LIMM(R02,0x7);
SMEM0(R00,T_VOID,P02);
SMEM0(R00,T_VOID,P02); // 二重書き込みはOK
LMEM0(R00,T_VOID,P02); // 読み出しもOK
// PSMEM0(P03,T_VOID,P02); // 同じ所に別の型で書き込んではダメ
// PLMEM0(P03,T_VOID,P02); // 同じ所を別の型で読み出してはダメ
PADD(P03,T_VOID,P02,R01);
junkApi_malloc(P04, T_UINT32, 1024 * 1024);
PSMEM0(P04,T_VOID,P03); // まだ書き込みが無い所に別の型で書き込むのはOK
PLMEM0(P04,T_VOID,P03); // もちろん、読み出しもOK
// SMEM0(R01,T_VOID,P03);
// LMEM0(R02,T_VOID,P03);
PADD(P05,T_VOID,P03,R02);
// SMEM0(R01,T_VOID,P05); // ポインタを代入した場所から32バイトには整数データもポインタも代入できない
PADD(P05,T_VOID,P05,R01);
SMEM0(R02,T_VOID,P05); // 32バイトを超えれば書き込みOK
LMEM0(R02,T_VOID,P05);
PADD(P05,T_VOID,P05,R01);
PCP(P06,P05);
PCP(P07,P06);
PADD(P05,T_VOID,P05,R01);
// PSMEM0(P04,T_VOID,P05); // 最後尾から28バイト領域にはポインタを書き込む事はできない(はみ出しを禁止)
SMEM0(R02,T_VOID,P05); // 最後尾28バイト領域はmalloc時に整数データフラグが設定される
PADD(P06,T_VOID,P06,R02);
SMEM0(R02,T_VOID,P06); // 整数データはギリギリまで書ける
PSMEM0(P04,T_VOID,P07); // 最後尾から32バイトならポインタを書き込める
// SMEM0(R02,T_VOID,P06); // ただし、一度ポインタを書き込むとその後ろの領域には整数データを書き込めなくなる
32ビットのT_VOID型というのを新しく作りました。T_VOID型配列にはポインタも整数データも突っ込めちゃいます。だだし、この汎用コンテナはmallocでしか作れません。まあ、tallocにも容易に実装できるのですが、用途を考えると、あまりtallocでは使わないかなぁ、と。
さて、この汎用コンテナ、「何でも突っ込める=セキュリティが疎かになる」なんて事はありません。その代わり、一部制限があります。
詳しい事は上のコードを読んで下さい。(ASKA書けないので、OSECPUのアセンブラで書きました。可読性低くてごめんなさい)上記のコードでコメントアウトされているのは、実行するとセキュリティエラーになるコードです。
ちなみに、汎用コンテナにポインタを書き込む時、型指定は(整数データを書き込む時も含め)T_VOIDですが、実際に書き込まれるのはT_VPTR(256ビット)です。ゆえに、ポインタを書き込んだ後ろにまた新しいデータを書き込みたいと思ったら、ポインタレジスタを8(<T_VPTR型のサイズ>/<T_VOID型のサイズ>=256/32=8)だけずらさなければいけません。
コメント | お名前 | NameLink | |