* ASKAでOSASKアプリを作ってみよう、のページ -(by [[K]], 2004.12.12) -前半はnask編とほとんど同じです。 --nask編はこちら → [[guide/nask]] *** まずは開発環境の入手 -この記述は数ヶ月以内に更新されそうですが、とりあえず現状重視で。 -[[downloads/dev]]のページへ行って、''最新版''のところの、「osa_dir2」というやつをダウンロードしてください。 --2MB強ありますが、これはCコンパイラとかテストラン用のOSASKやエミュレータなどが入っているせいです。すみません。 -これをどこでもいいですので、適当なところに解凍します。 *** プロジェクト作成 -次に、新規にアプリを作りますので、z_new_oというディレクトリを探してください。これをコピーして、同じディレクトリにペーストします。すると、「コピー ~ z_new_o」とかいう名前のフォルダができます。これを「askahelo」にリネームしてください。 --もちろん他の好きな名前でもいいですよ。 -改名が済んだら、askaheloの中に入って、Makefileを探し、これをテキストエディタで開きます。とりあえずはメモ帳で十分です。 -そして一番上の行のTARGETの記述を以下のように直します。 TARGET = askahelo -最後にnaskheloの中で 右クリック→新規作成→テキストドキュメント とやって、新規テキストドキュメントを作ります。そしてこれを、「askahelo.ask」に改名します。拡張子を変更するとどうたらこーたらとかいいますが、無視してOKしてください。 *** ソース作成 -さて、それではaskahelo.askを開いて、以下のソースをがしがしと入力してください。 --asmout文の中以外では、大文字小文字の区別があるので注意してください。 segment CODE(USE32, PARA); /* おまじない */ default(code == CODE); /* おまじない */ asmout("[FILE 'askahelo.ask']"); /* nask編参照 */ asmout("GLOBAL _OsaskMain"); /* 最初の[SECTION .text]は省略可能なので省略 */ void _OsaskMain() { asmout("MOV EBX,data.func_init"); /* ASKAはラベルへのgoto以外はうまくできないので、やむなくasmout。 */ CALL(0xc7, 0); asmout("MOV EBX,data.func_openwin"); CALL(0xc7, 0); asmout("MOV EBX,data.func_titlebox"); CALL(0xc7, 0); asmout("MOV EBX,data.func_settitle"); CALL(0xc7, 0); asmout("MOV EBX,data.func_sleep"); CALL(0xc7, 0); /* 永久スリープなので帰ってこない */ } asmout("[SECTION .data]"); void data() { ALIGNB(4); func_init: asmout("DD 0x0004, data.work, 0x0000"); /* ファンクション番号0x04(API初期化), ワークエリアのポインタ, 終了ファンクション番号0x00 */ func_openwin: asmout("DD 0x0020, data.window, 0x0200, 18 * 8, 3 * 16, 0x0000"); /* ファンクション番号0x20(ウィンドウオープン), window構造体のポインタ, スロット番号0x200, xサイズ(ドット単位), yサイズ(ドット単位), 終了ファンクション番号0x00 */ func_titlebox: asmout("DD 0x0028, 0x1000, data.wintitle, 0, 8, 1, 0, 0, data.window, 0x00c0, 0, 0x0000"); /* ファンクション番号0x28(テキストボックスオープン), オプション0x1000(ウィンドウタイトルモード), textbox構造体のポインタ, 背景色0, xサイズ(キャラクタ単位), yサイズ(キャラクタ単位), 表示x位置0, 表示y位置0, window構造体のポインタ, 標準キャラクタセット使用(0x00c0), 空白キャラクタ0, 終了ファンクション番号0x00 */ func_settitle: asmout("DD 0x0040, 0x1000, 0, 0, data.wintitle, 0, 0, 0, 8, 'askahelo', 0x0000"); /* ファクション番号0x40(テキスト表示), オプション0x1000(8bitキャラクタモード), 表示x位置0, 表示y位置0, textbox構造体のポインタ, 文字色0, 背景色0, キャラクタコードオフセット0, 文字数8, 文字列"naskhelo", 終了ファンクション番号0x00 */ func_sleep: DD(0x0018, 0x0001, 0, 0, 0x0000); /* ファンクション番号0x0018(シグナル関係の処理), オプション1(スリープ), パラメータ0, パラメータ0, 終了ファンクション番号0x00 */ ALIGNB(16); work: RESB(256); /* func_initに必要な256バイトのワークエリア */ window: RESB(128); /* ウィンドウ構造体 */ wintitle: RESB(64); /* テキストボックス構造体 */ RESB(64); /* 8文字分 (8 * 1 * 8) */ } *** どうやってアセンブルするの? -まず、コンソールを開きます。開き方は使っているOSによって違います。 --Win2000, WinXPなどのNT系: !cons_nt.batをダブルクリック --Win95, Win98などの9X系: !cons_9x.batをダブルクリック -コンソールが出てきたら、makeとだけうってEnterを押してください。 -これだけでリンクまで全自動でやってくれます。 -できたアプリは、askahelo.binです。 --osa_dir2で作った場合は多分160バイトです。 --nask版よりも1バイト小さいのは、ウィンドウタイトルの違いのせいです。ウィンドウタイトルを同じにすると、1バイトも違いません(サイズだけではなく、内容も)。 *** どうやってテスト実行するの? -同じくコンソールから、make runとだけうってEnterを押してください。 -しばらく待っていると、勝手にOSASKがエミュレータ環境で起動します。 -で、pokonの一番上の、 !BUILT.BIN を実行してください。 -うまくいけばウィンドウが表示されます。 *** ほかのアセンブラになれている人へ -ASKAはあまりおすすめできない''アセンブラ''です。読むのはそんなに大変ではないのですが、書くのはえらく骨が折れます。また、将来ASKAの文法はマシになるような気がするので、わざわざ今の癖の強い書き方を覚えることもないでしょう。 -asmout文の中はnaskの文法で書きます。不明なところは[[guide/nask]]を見てください。 -asmout("[section .bss]");を使えばBSSも使えるはずなのですが、osa_dir2のnaskは古いので、うまくいきません。全部.dataセクションにいれちゃってください。大丈夫です、オールゼロのデータは適当に圧縮されるのでほとんど問題ありません。 --.bssが使えるバージョンをパッケージしたらここの記述は直しますね。 -RESB文は何かと言うと、DB dupみたいなものです。 RESB 256 は DB 256 dup (0) に相当します。 --ASKAもnaskでも、DBなどでdup構文を使うことはできません。 -ASKAでは、 #define とか #include が使えます。 #if も #else も #endif もつかえます(というかCのプリプロセッサをそのまま使っています)。 *** ほかのOSのAPIになれている人へ -OSASKではAPI呼び出しはメモリを経由したポインタ渡しです。メモリにファンクション番号とパラメータを並べて、その先頭アドレスをEBXにいれて、CALL 0xc7:0をするだけです。正常終了する限りにおいて、EBX以外のレジスタは保存されます(ファンクション0x04を除く)。フラグは保存されません。 -毎回.dataセクションにパラメータをだらだら書かないといけないのか、という誤解をする人がいますが、そんなことはありません。スタック渡しっぽいことも簡単にできます。たとえばfunc_initの呼び出しは、以下のようにやってもいいのです。 PUSH(0); asmout("PUSH data.work"); PUSH(4); EBX = ESP; CALL(0xc7, 0); ESP += 12; -OSASKアプリのメモリモデルは、DS == ES == SS != CS です。つまり.textセクション内のデータにアクセスするにはCS:プリフィクスが必須です。また、PUSH(CS); POP(ES);などをやってESにCSのセレクタを代入しても、.textセクションの内容を書き換えることはできません。リードオンリーです。無理やり書き換えようとすれば、一般保護例外になるだけです。 --ということが面倒極まりないので、普通は全部のデータを.dataセクションにおきます。リードオンリーのデータも.dataセクションに置いちゃいます。そうすればややこしいセグメントに悩まされずに済みますからね。 *** 雑な説明 -結局のところ、これはAPI呼び出しCALLを5回やって、5つのAPIを実行しているだけです。 -OSASKのAPIでは、必ず最後に終了ファンクション0x0000があります。これを書かないと、その次も通常ファンクションだとみなされます。逆にこの例の場合、5つのファンクションをつなげることもできるわけです。そうすればCALLは1回で済みます。 -ファンクション0x0004は、[[gg00man/others]]の''lib_init''に相当します。 --ASKAでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 -ファンクション0x0020は、[[gg00man/window]]の''lib_openwindow''に相当します。 --ASKAでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 -ファンクション0x0028は、[[gg00man/text]]の''lib_opentextbox''に相当します。 --ASKAでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 -ファンクション0x0040は、[[gg00man/text]]の''lib_putstring1''に相当します。 --optのbit14が0になっているところが違いますが。 -ファンクション0x0018は、[[gg00man/signal]]の''lib_waitsignal''に相当します。 -それぞれについてパラメータの意味などは上記の説明を参考にしてください。 *** もっと詳しく説明してくれー -そのうちやるかもしれません。このページは長くなったので別のページで。 -ほかのAPIとかも。 ~ ~ -待てない人のための参考資料: --I.Tak.さんのAPI資料: http://user.ecc.u-tokyo.ac.jp/~t40370/osask/p0cref.html --[[GUIGUI00_man]] * こめんと欄 -ASKAによるプログラミングはおすすめしがたいところがあるので、このページはネタです。 -- [[K]] SIZE(10){2004-12-12 (日) 20:07:06} -定数計算まわりのじゃじゃ馬なところが改善されて、naskレベルのラベルをthrouchしてくれる機能があれば、結構おすすめできるんですけどねえ・・・。 -- [[K]] SIZE(10){2004-12-12 (日) 20:09:04} #comment