* OSECPU-ASKA入門 #0006 -(by [[K]], 2013.07.03) ** (0) はじめに -以下の記事はver.0.54のWindows版を前提にしています。他の版を使っている場合は適宜読み替えてください。 --たとえば osecpu054d.zip とかのことです ~ -もくじ --[[page0036]]: #0000 --[[page0037]]: #0001 --[[page0038]]: #0002 --[[page0039]]: #0003 --[[page0044]]: #0004 --[[page0045]]: #0005 --[[page0048]]: #0006 ** (1) rand -junkApi_rand(_i, max); : --適当な乱数を返します。OSECPUでは起動時にシステムが適当な方法でseedを与えてくれるので、毎回異なった乱数系列を期待することができます。 --もちろんseedをアプリで指定し、系列を選択することもできます。 --このAPIによって 0 <= i <= max の乱数が返ります。 --maxが0のときは、iの値はSInt32の任意の値を取ることになります。 ** (2) putString2 -junkApi_putString2(len, s); : --junkApi_putConstStringは文字定数のみが指定可能でしたが、これはT_UINT8な配列を指定可能なものです。 --末尾の2は、これが内部的には文字列表示APIのモード2を利用していることを表しているので、putString1の改良版という意味ではありません。 ---ちなみに文字列表示APIはモード0からモード6まであります。 --この機能は OSECPU ver.0.55 から使えます。 --lenに文字数を入れて(定数かRxx)、sにはPxxを入れてください。 ** (3) ポインタ型変数 -上記の(2)の説明を書いてから気が付きました。実はここまでまったくポインタ型変数の話を書いていなかったと。これではいけないので、書きます。そろそろ書いてもいい時期です。 -以下のような構文で変数を宣言することができます。 VPtr p:P01; -これはpという変数を宣言しており、P01というレジスタに割り当てられます。要するに、pはP01の別名でしかないのです。 -変数名は整数型変数の時と同様に大文字小文字を区別しますので、pとPを使い分けることができます。 -レジスタ名はP00~P3Fまでが有効ですが(後ろの2桁は16進数になっている)、とりあえずP01~P1Fまでを自由に使うのがいいと思います。・・・これは言い換えれば31個しかないということでもあります。ポインタ型変数は最大で31個しか作れないのです!これはつらい!! --いやでも実際のところ、31個で足りないと思うことはあまりないのではないかと思います。今までポインタ型変数は全く使わなくてもどうにかなってきたわけですし、まあ使っても数個じゃないでしょうか? -ちなみにVPtrはVoidPtrの略です。C言語で言うところの void * です。 --本当は int32s * や、UINT8 * などのように型を記述できるようにしたいのですが、ASKAのほうが十分に対応できていません。OSECPU側は準備完了しているのですが・・・。 --本当は int32s * や、UInt8 * などのように型を記述できるようにしたいのですが、ASKAのほうが十分に対応できていません。OSECPU側は準備完了しているのですが・・・。 -ポインタとは一体何なのか・・・。C言語とかになれていない人向けに言うとしたら、まあ配列変数と言ったところでしょうか。本当はもっといろいろな使い方ができるのですが、ひとまずは配列変数だということにして、説明をしていきたいと思います。 ** (4) ポインタの配列変数的用法 -ところで、 VPtr p:P01; -みたいに書いたとしても、それですぐにpを配列変数として利用できるわけではありません、残念ながら。まだしなければいけない準備があるのです。 junkApi_malloc(p, T_SINT32, 100); -これを実行すると、p[0]からp[99]までの合計100個が使えるようになります。それぞれの要素は符号付きの32bit整数です。 -しかし・・・ASKAは例によってまだおバカさんなので、p[0]という書き方を理解できません。ということで以下のように書きます。 i = 0; // SInt32 i:R00, j:R01; とかを事前にやっておく. PALMEM0(j, T_SINT32, p, i); // j = p[i]; の代わり. PASMEM0(j, T_SINT32, p, i); // p[i] = j; の代わり. // PALMEMのあとの文字は、オーではなくゼロです、PASMEM0もゼロです. -OSECPUは少しでも命令種を減らすために、定数が指定できない場合があります。配列の添え字もまさにそれに当たります(上記の例ではi)。ということで、面倒でも適当な変数に代入してください。 -OSECPUはセキュアなOSなので、仮にmallocをやる前にPASMEM0(...)とかやっちゃっても、その場合はエラーが出て止まってくれます。さらにmallocのときと違う型でアクセスしようとしたときもエラーが出て止まってくれます。添え字には0から99までしか指定できないのに、この範囲外の数字を指定してしまった時にもエラーが出て止まってくれます。 -エラーの時は(リリースモードでamakeしてなければ)、ソースコード上の行番号がわかります。エラーの種類は分かりません。エラーを起こした時のレジスタの値も確認できます。まあこの辺の話はもう少し先できちんと説明したいと思います。 -整数レジスタの変数の時は、int32s(SInt32)の一種類しかありませんでしたが、配列変数になると、たくさんの種類が選べます。これは主にメモリの節約のためです。消費メモリとか気にしなくていいときは、T_SINT32にしてしまうのが気楽でいいと思います。これならレジスタ変数の値がそのまま保持できます。面倒なことは何もありません。 -それ以外の型ですと、保持できない数値を代入してしまった時には、読み出し時に何が出てくるかは不定になります。 -malloc直後の配列変数の値は、基本的にすべて不定です。もし0に初期化したいのであれば、自分で初期化してください。 ~ -ASAKでは、配列を式の中に混ぜて表記する方法をまだサポートできていません。PALMEM0()などで値を整数変数に読み込んでから使うことになります。 -PASMEM0(j, T_SINT32, p, i); についても、このjやiの部分に式を使うことはできず、整数レジスタ1つだけを指定するわけです。 --早く p[i] = j + 5; とか書けるようになりたいです! -利用可能な型は次の通りです。 --T_SINT8, T_UINT8, T_SINT16, T_UINT16, T_SINT32, T_UINT32 : 一般的な型 --T_SINT4, T_UINT4, T_SINT2, T_UINT2, T_SINT1, T_UINT1 : 少ないビット数の型 ---T_UINT1は、0か1しか保持できません ---T_SINT1は、0か-1しか保持できません --T_SINT12, T_UINT12, T_SINT20, T_UINT20, T_SINT24, T_UINT24, T_SINT28, T_UINT28 : 中途半端なビット数の型 --T_VPtr : ポインタ型変数を保持できる型 -(つづく) * こめんと欄 #comment