page0095
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* OSECPU-ASKA入門 #0014
-(by [[K]], 2013.06.26)
** (0) はじめに
-以下の記事はosecpu117dのWindows版を前提にしています。他...
--ちなみに[[page0074]]を読めばrev2の最新版が見つかります。
~
-もくじ
--[[page0087]]: #0010
--[[page0088]]: #0011
--[[page0089]]: #0012
--[[page0093]]: #0013
--[[page0095]]: #0014
** (1) 関数の作り方、呼び出し方
-今回は予定とは違った順番なりますが、関数の話を書きます。
-与えられた二つの数字を加算して結果を返す関数を作って呼ん...
-まずは関数名を決めます。・・・funcにしますね。
-じゃああとは成り行きで作ってみます。
#include "osecpu_ask.h"
#define L_func LOCAL(0)
LOCALLABELS(1);
#define func(_r, a, b) R30=a; R31=b; CALL(L_func); _r=R30
// main
do {
func(R00, 2, 3);
api_fillRect(MODE_COL3, R00, 16, 16, 0, 0);
}
api_end(); // これがないと下の関数を再度実行して無限...
beginFunc(L_func);
do {
Int32s a:R30, b:R31, r:R30;
r = a + b;
}
endFunc();
-これを実行すると、画面にピンクの四角が表示されるはずです...
~
-さて、それでは一つずつ説明していきます。
-まず do { ... } ですが、これの実体は1度だけ実行するfor文...
--C言語なら単に { ... } と書くところですよね。ASKAはおバ...
-関数を作るときは、"L_"を頭につけた定数を#defineする必要...
-そして#defineの内容はLOCAL(0)とかLOCAL(1)とか、そういう...
-LOCALLABELS(?);は、LOCAL(?)で付けた番号の最大値+1をASKA...
-さて次はこれです:
#define func(_r, a, b) R30=a; R31=b; CALL(L_func); _r=R30
-これは、関数呼び出しをかっこよく見せるための#defineです。
--OSECPU-VMでは引数はR30~R3Bを使って渡します。そして結果...
--これに逆らってもいいのですが、その場合はいろいろと面倒...
--註:C言語などとは違って、複数の値を返せます。これはちょ...
-関数funcの中身ですが、この中ではR30とR31しか使っていませ...
-そしてR00~R1Fに関しては、いろいろ使って適当な値を代入し...
--違う書き方をすると、R00~R27までを自由に使えるようにな...
** (2) 再帰呼び出しの例
-次は階乗を計算するプログラムの例です。
#include "osecpu_ask.h"
#define L_func LOCAL(0)
LOCALLABELS(1);
#define func(_r, a) R30=a; CALL(L_func); _r=R30
// main
do {
Int32s ans:R00;
func(ans, 10);
api_putStringDec('\1', ans, 10, 1); // 「OSECPU-...
}
api_end(); // これがないと下の関数を再度実行して無限...
beginFunc(L_func);
do {
Int32s _a:R30, _r:R30, a:R00, b:R01;
a = _a; // R30以降のレジスタは、関数呼び出しやAP...
if (a > 1) {
b = a - 1;
func(b, b); // b = func(a - 1);
a *= b; // a = a * func(a - 1);
}
_r = a;
}
endFunc();
** (3) 関数呼び出しに関する中級テクニック
-関数呼び出しにおいては、引数をR30以降に格納するのが基本...
-ただし、R00~R1Fの値を変更しても呼び出し元に影響できない...
#include "osecpu_ask.h"
#define L_func LOCAL(0)
LOCALLABELS(1);
#define func_R00_R30() CALL(L_func) // R00で値を渡す...
// main
do {
Int32s ans:R00;
R00 = 10; func_R00_R30(); ans = R30;
api_putStringDec('\1', ans, 10, 1);
}
api_end(); // これがないと下の関数を再度実行して無限...
beginFunc(L_func);
do {
Int32s _r:R30, a:R00, b:R01;
_r = a;
if (a > 1) {
b = a;
a--;
func_R00_R30();
_r *= b; // _r = a * func(a - 1);
}
}
endFunc();
** つづく
-[[page0098]]につづく
* こめんと欄
#comment
終了行:
* OSECPU-ASKA入門 #0014
-(by [[K]], 2013.06.26)
** (0) はじめに
-以下の記事はosecpu117dのWindows版を前提にしています。他...
--ちなみに[[page0074]]を読めばrev2の最新版が見つかります。
~
-もくじ
--[[page0087]]: #0010
--[[page0088]]: #0011
--[[page0089]]: #0012
--[[page0093]]: #0013
--[[page0095]]: #0014
** (1) 関数の作り方、呼び出し方
-今回は予定とは違った順番なりますが、関数の話を書きます。
-与えられた二つの数字を加算して結果を返す関数を作って呼ん...
-まずは関数名を決めます。・・・funcにしますね。
-じゃああとは成り行きで作ってみます。
#include "osecpu_ask.h"
#define L_func LOCAL(0)
LOCALLABELS(1);
#define func(_r, a, b) R30=a; R31=b; CALL(L_func); _r=R30
// main
do {
func(R00, 2, 3);
api_fillRect(MODE_COL3, R00, 16, 16, 0, 0);
}
api_end(); // これがないと下の関数を再度実行して無限...
beginFunc(L_func);
do {
Int32s a:R30, b:R31, r:R30;
r = a + b;
}
endFunc();
-これを実行すると、画面にピンクの四角が表示されるはずです...
~
-さて、それでは一つずつ説明していきます。
-まず do { ... } ですが、これの実体は1度だけ実行するfor文...
--C言語なら単に { ... } と書くところですよね。ASKAはおバ...
-関数を作るときは、"L_"を頭につけた定数を#defineする必要...
-そして#defineの内容はLOCAL(0)とかLOCAL(1)とか、そういう...
-LOCALLABELS(?);は、LOCAL(?)で付けた番号の最大値+1をASKA...
-さて次はこれです:
#define func(_r, a, b) R30=a; R31=b; CALL(L_func); _r=R30
-これは、関数呼び出しをかっこよく見せるための#defineです。
--OSECPU-VMでは引数はR30~R3Bを使って渡します。そして結果...
--これに逆らってもいいのですが、その場合はいろいろと面倒...
--註:C言語などとは違って、複数の値を返せます。これはちょ...
-関数funcの中身ですが、この中ではR30とR31しか使っていませ...
-そしてR00~R1Fに関しては、いろいろ使って適当な値を代入し...
--違う書き方をすると、R00~R27までを自由に使えるようにな...
** (2) 再帰呼び出しの例
-次は階乗を計算するプログラムの例です。
#include "osecpu_ask.h"
#define L_func LOCAL(0)
LOCALLABELS(1);
#define func(_r, a) R30=a; CALL(L_func); _r=R30
// main
do {
Int32s ans:R00;
func(ans, 10);
api_putStringDec('\1', ans, 10, 1); // 「OSECPU-...
}
api_end(); // これがないと下の関数を再度実行して無限...
beginFunc(L_func);
do {
Int32s _a:R30, _r:R30, a:R00, b:R01;
a = _a; // R30以降のレジスタは、関数呼び出しやAP...
if (a > 1) {
b = a - 1;
func(b, b); // b = func(a - 1);
a *= b; // a = a * func(a - 1);
}
_r = a;
}
endFunc();
** (3) 関数呼び出しに関する中級テクニック
-関数呼び出しにおいては、引数をR30以降に格納するのが基本...
-ただし、R00~R1Fの値を変更しても呼び出し元に影響できない...
#include "osecpu_ask.h"
#define L_func LOCAL(0)
LOCALLABELS(1);
#define func_R00_R30() CALL(L_func) // R00で値を渡す...
// main
do {
Int32s ans:R00;
R00 = 10; func_R00_R30(); ans = R30;
api_putStringDec('\1', ans, 10, 1);
}
api_end(); // これがないと下の関数を再度実行して無限...
beginFunc(L_func);
do {
Int32s _r:R30, a:R00, b:R01;
_r = a;
if (a > 1) {
b = a;
a--;
func_R00_R30();
_r *= b; // _r = a * func(a - 1);
}
}
endFunc();
** つづく
-[[page0098]]につづく
* こめんと欄
#comment
ページ名: