何か自分用のメモとして記事の形で残しておきたかったのだが
何をメモしたかったのか忘れた
脳の老化ひどい
comet2/casl2において
サブルーチン(コルーチン?プロシージャ?関数?わからん)て何か思ったことなど
(まぁググレば答えは出てきそうだが、自分で考えてみるなど)
・引数をコールスタックに積む
JVMとかC/C++あたりではそうやってそうだけど(C/C++は積み方や除き方が色々あるみたいだけど)
それが出来るのはコールスタックの指定した位置のメモリーにアクセスできるからなんだよね
JVMはアクセスするための専用命令がって
C/C++ではスタックポインタの示すアドレス値から計算するコードが埋め込まれるわけで
一方、comet2はcpu実装に依存しない命令範囲だと、スタックポインタにアクセスする手段がなく、JVMのような指定位置にアクセスするような命令もない・・・
スタックの先頭への入れる出すの命令はあるんだけど・・・
call命令でジャンプするとスタックの先頭に戻りのアドレス値が積まれてしまうから引数をスタックに積んでると色々と辛い
・引数をレジスタで渡す
C++は知らんけどCではできそう(registerとかいう記憶子(?)で引数を修飾するといいんだっけか?まぁこの指定はお気持ち表明するだけでコンパイラさんがその通りやってくれるわけではないらしいが(構造的にできない場合もあるだろし))
comet2では妥当な選択なような気はする
スーパバイザコール(SVC)なんかもレジスタ経由で渡すようだし
レジスタの数を超える引数を与えたいって場合は厳しいけど(そういう状況はプログラムの設計ミスな気もしなくもないけど、構造体作って詰め込んで構造体の先頭アドレス渡せばいいわけだし)
レジスタは有限なので引数で確保されると少し辛い
・戻り値
JVM/C/C++でどうやってるか把握してない(たぶんスタックに積む?)
comet2、戻り先のアドレスが先頭にあるスタックに戻り値を積むしてretしたら死んじゃうね・・・
まぁレジスタに入れたいところだが、レジスタに収まらない戻り値だって時にはありそうだし
現実的には出力先のアドレスを引数で受け取ってそこに書き込む、処理の成否をレジスタに書きこむ、あたりかな・・・
・ローカル変数
JVMやC/C++ではコールスタック上にその領域が確保されるわけだが、それはスタックメモリにアクセスできる手段があるしね・・・(C/C++では場合によっては領域としてレジスタ使われるし、Cではregisterを変数宣言につけておけばお気持ち表明できるし)
comet2ではスタックに容易にアクセスできないため、ローカル変数使用でレジスタで足りぬ場合は辛い・・・
casl2におけるDSで確保したメモリを使うという手段は可能だが、まぁこれ共有メモリ相当だから、再帰関数のような再帰的処理で問題がある・・・
(マルチスレッドでも問題になるし、共有ライブラリとして単一メモリ割り当てられたらマルチプロセスでも危なそう、comet2のスペック的にそれらの実現が可能かは知らんけど(タイマ割り込みでOSが切り替えるわけでど基本命令セットにスタックポインタ操作できるものないしcpu実装依存かもだが))
まぁ再帰的処理で大量ローカル使う状況があったとして
要するに動的メモリを練成できればローカル変数も使えなくもない(?)
casl2のDSで動的メモリ用のメモリを確保して
メモリ要求に応じてメモリ領域を提供し、解放要求で該当メモリの領域解放するようなサブルーチンを作る・・・と
要するにallocとfreeの関数みたいな?
メモリアロケーション、OS側が方法を用意してたりしそうだけど
そうでない場合もあるらしい
OSの方法で細かいメモリ要求するのではなく、OSの方法で事前に大きいメモリ確保しておいて独自の方法で分配する、みたいな?(よく知らん)
まぁcomet2ではcasl2でのDSの領域でやりくりするしかないだろうけど・・・
(どうせcomet2の実装なんてメモリ保護なんてなさそうだから任意の領域の書き換え可能だろうけど())
↓コレ関連のメモでした。おわり。
https://bitbucket.org/neetsdkasu/basic-to-casl2/src/1-basic/