1: 2004-12-12 (日) 18:54:44 [6] | 2: 2004-12-12 (日) 20:09:04 [7] | ||
---|---|---|---|
Line 20: | Line 20: | ||
*** ソース作成 | *** ソース作成 | ||
-さて、それではaskahelo.askを開いて、以下のソースをがしがしと入力してください。 | -さて、それではaskahelo.askを開いて、以下のソースをがしがしと入力してください。 | ||
- | --ニーモニックやレジスタ名が大文字になっていますが、もちろん小文字でも構いません。 | + | --asmout文の中以外では、大文字小文字の区別があるので注意してください。 |
segment CODE(USE32, PARA); /* おまじない */ | segment CODE(USE32, PARA); /* おまじない */ | ||
default(code == CODE); /* おまじない */ | default(code == CODE); /* おまじない */ | ||
Line 27: | Line 27: | ||
asmout("GLOBAL _OsaskMain"); | asmout("GLOBAL _OsaskMain"); | ||
- | /* 最初の[section .text]は省略可能なので省略 */ | + | /* 最初の[SECTION .text]は省略可能なので省略 */ |
void _OsaskMain() | void _OsaskMain() | ||
Line 41: | Line 41: | ||
} | } | ||
- | asmout("[section .data]"); | + | asmout("[SECTION .data]"); |
void data() | void data() | ||
Line 51: | Line 51: | ||
func_openwin: | func_openwin: | ||
- | asmout("DD 0x0020, data.window, 0x0200, 18 * 3, 3 * 16, 0x0000"); | + | asmout("DD 0x0020, data.window, 0x0200, 18 * 8, 3 * 16, 0x0000"); |
/* ファンクション番号0x20(ウィンドウオープン), window構造体のポインタ, スロット番号0x200, | /* ファンクション番号0x20(ウィンドウオープン), window構造体のポインタ, スロット番号0x200, | ||
xサイズ(ドット単位), yサイズ(ドット単位), 終了ファンクション番号0x00 */ | xサイズ(ドット単位), yサイズ(ドット単位), 終了ファンクション番号0x00 */ | ||
- | |||
- | |||
- | |||
func_titlebox: | func_titlebox: | ||
- | DD 0x0028, 0x1000, wintitle, 0, 8, 1, 0, 0, window, 0x00c0, 0, 0x0000 | + | asmout("DD 0x0028, 0x1000, data.wintitle, 0, 8, 1, 0, 0, data.window, 0x00c0, 0, 0x0000"); |
- | ; ファンクション番号0x28(テキストボックスオープン), オプション0x1000(ウィンドウタイトルモード), textbox構造体のポインタ, 背景色0, | + | /* ファンクション番号0x28(テキストボックスオープン), オプション0x1000(ウィンドウタイトルモード), |
- | ; xサイズ(キャラクタ単位), yサイズ(キャラクタ単位), 表示x位置0, 表示y位置0, window構造体のポインタ, | + | textbox構造体のポインタ, 背景色0, xサイズ(キャラクタ単位), yサイズ(キャラクタ単位), |
- | ; 標準キャラクタセット使用(0x00c0), リザーブ0, 終了ファンクション番号0x00 | + | 表示x位置0, 表示y位置0, window構造体のポインタ, 標準キャラクタセット使用(0x00c0), |
+ | 空白キャラクタ0, 終了ファンクション番号0x00 */ | ||
func_settitle: | func_settitle: | ||
- | DD 0x0040, 0x1000, 0, 0, wintitle, 0, 0, 0, 8, "naskhelo", 0x0000 | + | asmout("DD 0x0040, 0x1000, 0, 0, data.wintitle, 0, 0, 0, 8, 'askahelo', 0x0000"); |
- | ; ファクション番号0x40(テキスト表示), オプション0x1000(8bitキャラクタモード), 表示x位置0, 表示y位置0, textbox構造体のポインタ, | + | /* ファクション番号0x40(テキスト表示), オプション0x1000(8bitキャラクタモード), |
- | ; 文字色0, 背景色0, キャラクタコードオフセット0, 文字数8, 文字列"naskhelo", 終了ファンクション番号0x00 | + | 表示x位置0, 表示y位置0, textbox構造体のポインタ, 文字色0, 背景色0, キャラクタコードオフセット0, |
+ | 文字数8, 文字列"naskhelo", 終了ファンクション番号0x00 */ | ||
func_sleep: | func_sleep: | ||
- | DD 0x0018, 0x0001, 0, 0, 0x0000 | + | DD(0x0018, 0x0001, 0, 0, 0x0000); |
- | ; ファンクション番号0x0018(シグナル関係の処理), オプション1(スリープ), パラメータ0, パラメータ0, 終了ファンクション番号0x00 | + | /* ファンクション番号0x0018(シグナル関係の処理), オプション1(スリープ), パラメータ0, |
+ | パラメータ0, 終了ファンクション番号0x00 */ | ||
- | ALIGNB 16 | + | ALIGNB(16); |
work: | work: | ||
- | RESB 256 ; func_initに必要な256バイトのワークエリア | + | RESB(256); /* func_initに必要な256バイトのワークエリア */ |
window: | window: | ||
- | RESB 128 ; ウィンドウ構造体 | + | RESB(128); /* ウィンドウ構造体 */ |
wintitle: | wintitle: | ||
- | RESB 64 ; テキストボックス構造体 | + | RESB(64); /* テキストボックス構造体 */ |
- | RESB 8 * 1 * 8 ; 8文字分 | + | RESB(64); /* 8文字分 (8 * 1 * 8) */ |
+ | } | ||
*** どうやってアセンブルするの? | *** どうやってアセンブルするの? | ||
Line 88: | Line 90: | ||
-コンソールが出てきたら、makeとだけうってEnterを押してください。 | -コンソールが出てきたら、makeとだけうってEnterを押してください。 | ||
-これだけでリンクまで全自動でやってくれます。 | -これだけでリンクまで全自動でやってくれます。 | ||
- | -できたアプリは、naskhelo.binです。 | + | -できたアプリは、askahelo.binです。 |
- | --osa_dir2で作った場合は多分161バイトです。 | + | --osa_dir2で作った場合は多分160バイトです。 |
+ | --nask版よりも1バイト小さいのは、ウィンドウタイトルの違いのせいです。ウィンドウタイトルを同じにすると、1バイトも違いません(サイズだけではなく、内容も)。 | ||
*** どうやってテスト実行するの? | *** どうやってテスト実行するの? | ||
Line 98: | Line 101: | ||
*** ほかのアセンブラになれている人へ | *** ほかのアセンブラになれている人へ | ||
- | -naskはMASMとかとは少し文法が違います。NASMの文法とほとんど同じです。 | + | -ASKAはあまりおすすめできない''アセンブラ''です。読むのはそんなに大変ではないのですが、書くのはえらく骨が折れます。また、将来ASKAの文法はマシになるような気がするので、わざわざ今の癖の強い書き方を覚えることもないでしょう。 |
- | -GLOBAL文はいわゆるPUBLIC文です。 | + | -asmout文の中はnaskの文法で書きます。不明なところは[[guide/nask]]を見てください。 |
- | -ラベルの扱いですが、何も書かないとみんなOFFSET指定とみなされます。というかOFFSETを書いたらエラーです。したがって | + | -asmout("[section .bss]");を使えばBSSも使えるはずなのですが、osa_dir2のnaskは古いので、うまくいきません。全部.dataセクションにいれちゃってください。大丈夫です、オールゼロのデータは適当に圧縮されるのでほとんど問題ありません。 |
- | MOV EBX,func_init | + | |
- | -は、EBXに4が入るわけではなく、アドレスが入ります。メモリを参照させたいときは、[]でくくります。 | + | |
- | MOV EBX,[func_init] | + | |
- | -こうすればEBXには4が入ります。 | + | |
- | -[section .bss]を使えばBSSも使えるはずなのですが、osa_dir2のnaskは古いので、うまくいきません。全部.dataセクションにいれちゃってください。大丈夫です、オールゼロのデータは適当に圧縮されるのでほとんど問題ありません。 | + | |
--.bssが使えるバージョンをパッケージしたらここの記述は直しますね。 | --.bssが使えるバージョンをパッケージしたらここの記述は直しますね。 | ||
-RESB文は何かと言うと、DB dupみたいなものです。 RESB 256 は DB 256 dup (0) に相当します。 | -RESB文は何かと言うと、DB dupみたいなものです。 RESB 256 は DB 256 dup (0) に相当します。 | ||
- | --NASMもnaskでも、DBなどでdup構文を使うことはできません。 | + | --ASKAもnaskでも、DBなどでdup構文を使うことはできません。 |
+ | -ASKAでは、 #define とか #include が使えます。 #if も #else も #endif もつかえます(というかCのプリプロセッサをそのまま使っています)。 | ||
*** ほかのOSのAPIになれている人へ | *** ほかのOSのAPIになれている人へ | ||
-OSASKではAPI呼び出しはメモリを経由したポインタ渡しです。メモリにファンクション番号とパラメータを並べて、その先頭アドレスをEBXにいれて、CALL 0xc7:0をするだけです。正常終了する限りにおいて、EBX以外のレジスタは保存されます(ファンクション0x04を除く)。フラグは保存されません。 | -OSASKではAPI呼び出しはメモリを経由したポインタ渡しです。メモリにファンクション番号とパラメータを並べて、その先頭アドレスをEBXにいれて、CALL 0xc7:0をするだけです。正常終了する限りにおいて、EBX以外のレジスタは保存されます(ファンクション0x04を除く)。フラグは保存されません。 | ||
-毎回.dataセクションにパラメータをだらだら書かないといけないのか、という誤解をする人がいますが、そんなことはありません。スタック渡しっぽいことも簡単にできます。たとえばfunc_initの呼び出しは、以下のようにやってもいいのです。 | -毎回.dataセクションにパラメータをだらだら書かないといけないのか、という誤解をする人がいますが、そんなことはありません。スタック渡しっぽいことも簡単にできます。たとえばfunc_initの呼び出しは、以下のようにやってもいいのです。 | ||
- | PUSH 0 | + | PUSH(0); |
- | PUSH work | + | asmout("PUSH data.work"); |
- | PUSH 4 | + | PUSH(4); |
- | MOV EBX,ESP | + | EBX = ESP; |
- | CALL 0xc7:0 | + | CALL(0xc7, 0); |
- | ADD ESP,12 | + | ESP += 12; |
-OSASKアプリのメモリモデルは、DS == ES == SS != CS です。つまり.textセクション内のデータにアクセスするにはCS:プリフィクスが必須です。また、PUSH(CS); POP(ES);などをやってESにCSのセレクタを代入しても、.textセクションの内容を書き換えることはできません。リードオンリーです。無理やり書き換えようとすれば、一般保護例外になるだけです。 | -OSASKアプリのメモリモデルは、DS == ES == SS != CS です。つまり.textセクション内のデータにアクセスするにはCS:プリフィクスが必須です。また、PUSH(CS); POP(ES);などをやってESにCSのセレクタを代入しても、.textセクションの内容を書き換えることはできません。リードオンリーです。無理やり書き換えようとすれば、一般保護例外になるだけです。 | ||
--ということが面倒極まりないので、普通は全部のデータを.dataセクションにおきます。リードオンリーのデータも.dataセクションに置いちゃいます。そうすればややこしいセグメントに悩まされずに済みますからね。 | --ということが面倒極まりないので、普通は全部のデータを.dataセクションにおきます。リードオンリーのデータも.dataセクションに置いちゃいます。そうすればややこしいセグメントに悩まされずに済みますからね。 | ||
Line 126: | Line 125: | ||
-OSASKのAPIでは、必ず最後に終了ファンクション0x0000があります。これを書かないと、その次も通常ファンクションだとみなされます。逆にこの例の場合、5つのファンクションをつなげることもできるわけです。そうすればCALLは1回で済みます。 | -OSASKのAPIでは、必ず最後に終了ファンクション0x0000があります。これを書かないと、その次も通常ファンクションだとみなされます。逆にこの例の場合、5つのファンクションをつなげることもできるわけです。そうすればCALLは1回で済みます。 | ||
-ファンクション0x0004は、[[gg00man/others]]の''lib_init''に相当します。 | -ファンクション0x0004は、[[gg00man/others]]の''lib_init''に相当します。 | ||
- | --naskでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 | + | --ASKAでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 |
-ファンクション0x0020は、[[gg00man/window]]の''lib_openwindow''に相当します。 | -ファンクション0x0020は、[[gg00man/window]]の''lib_openwindow''に相当します。 | ||
- | --naskでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 | + | --ASKAでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 |
-ファンクション0x0028は、[[gg00man/text]]の''lib_opentextbox''に相当します。 | -ファンクション0x0028は、[[gg00man/text]]の''lib_opentextbox''に相当します。 | ||
- | --naskでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 | + | --ASKAでの呼び出しでは、0を指定したら自動malloc、というサービスはありません。 |
-ファンクション0x0040は、[[gg00man/text]]の''lib_putstring1''に相当します。 | -ファンクション0x0040は、[[gg00man/text]]の''lib_putstring1''に相当します。 | ||
--optのbit14が0になっているところが違いますが。 | --optのbit14が0になっているところが違いますが。 | ||
Line 146: | Line 145: | ||
* こめんと欄 | * こめんと欄 | ||
- | -直ってしまったので、勝手に修正してしまいました。コメントアウトしてあります。 -- ''Zakky'' SIZE(10){2004-12-11 (土) 20:23:30} | + | -ASKAによるプログラミングはおすすめしがたいところがあるので、このページはネタです。 -- [[K]] SIZE(10){2004-12-12 (日) 20:07:06} |
- | -どうもありがとう。助かりました。 -- [[K]] SIZE(10){2004-12-11 (土) 20:52:16} | + | -定数計算まわりのじゃじゃ馬なところが改善されて、naskレベルのラベルをthrouchしてくれる機能があれば、結構おすすめできるんですけどねえ・・・。 -- [[K]] SIZE(10){2004-12-12 (日) 20:09:04} |
- | -とりあえずこんなものでどうでしょうか?>nikaさん リクエストがなければこの先は書かないでおきます。 -- [[K]] SIZE(10){2004-12-12 (日) 00:06:53} | + | |
- | -ありがとうございます。とりあえずいい感じです。 -- ''nika'' SIZE(10){2004-12-12 (日) 08:27:30} | + | |
#comment | #comment |
(This host) = http://osask.net