1: 2008-12-30 (火) 11:02:59 |
現: 2024-01-08 (月) 12:58:42 k-tan |
- | * ぐいぐい01に関するメモ-18 | + | TITLE:x |
| + | * ぐいぐい01に関するメモ-18 [#u8295563] |
| -(by [[K]], 2008.12.30) | | -(by [[K]], 2008.12.30) |
| -メモのうち重要な部分をそのうちまとめてまともなページを作る | | -メモのうち重要な部分をそのうちまとめてまともなページを作る |
- | *** (33) naskで「ぐいぐい01」アプリを作る | + | *** (33) naskで「ぐいぐい01」アプリを作る [#r48a57b8] |
- | -IRCで、なんとアセンブラで「ぐいぐい01」アプリを作ってみたいという人がいたので、その人の参考になりそうなことをメモしておく。その人の参考にならないとしても、nikaさんやDAsoranさんやI.Tak.さんみたいな人ならきっと参考になると思う(この三人に呼んで欲しいという意味ではなく、この三人くらいの人がOSASKコミュニティには時々出現してくれるから、将来のそういう人に役立てばそれでいいという意味)。 | + | -OSASK-IRCで、なんとアセンブラで「ぐいぐい01」アプリを作ってみたいという人がいたので、その人の参考になりそうなことをメモしておきます。その人の参考にならないとしても、nikaさんやDAsoranさんやI.Tak.さんみたいな人ならきっと参考になると思います(この三人に読んで欲しいという意味ではなく、この三人くらいの人がOSASKコミュニティには時々出現してくれるから、将来のそういう人に役立てばそれでいいという意味)。 |
- | - | + | ---- |
- | | + | -とりあえずhelloを書いてみましょう。 |
- | | + | ; ex0000.nas |
- | | + | [FORMAT "WCOFF"] |
- | | + | [FILE "ex0000.nas"] |
- | * こめんと欄 | + | [INSTRSET "i486p"] |
| + | [BITS 32] |
| + | GLOBAL _G01Main |
| + | |
| + | [SECTION .text] |
| + | |
| + | _G01Main: |
| + | MOV EAX,msg |
| + | CALL [ESI] |
| + | DB 0x53, 0x00 ; [5 (0) (!6_x) 3 EAX] ; 5 (0) (!6_x) 3 の後に!6がある |
| + | RET |
| + | |
| + | [SECTION .data] |
| + | |
| + | msg DB "hello, world", 0 |
| + | |
| + | -こんな感じかなあ。ESIの値はアプリ起動時に渡される値を使えば上記で問題はないです。また、EDIもアプリ起動時は0になっていることが保証されているので、これで問題ないです。APIパケットでは、わざわざEAXレジスタを使って文字列の位置を与えていますが、これはラベルの値を直接APIパケットに含める方法をまだ十分にはサポートできていないためです(申し訳ない)。レジスタにせよなんにせよ、とにかくAPIで扱うポインタはDSもしくはSSでアクセスできる範囲になくてはいけないので、文字列はわざわざ.dataセクションにおいています。 |
| + | -文字列の最後に0x0aが入っていませんが、これは入れても入れなくてもいいのです。「ぐいぐい01」では終了時に改行し忘れていると判断すれば、自動で改行してから終了しますので。 |
| + | -これをmakeするためのMakefileは次の通りです。 |
| + | TARGET = ex0000 |
| + | MODE = g01 |
| + | OBJS = ex0000.obj |
| + | |
| + | INCPATH = ../z_tools/guigui01/ |
| + | include ../z_tools/com_mak.txt |
| + | -これを使ってmakeすると、60バイトのex0000.g01と56バイトのex0000.orgができるはずです。どっちを使えばいいの?と思うかもしれませんが、60バイトはtek5をかけた場合の大きさで、tek5しなければ56バイトなのです。つまり、.g01のほうは無視して、.orgのほうを使いましょう(.g01を消して.orgを.g01と改名してもいいです)。 |
| + | -56バイトってどういうこと!?17バイトになるんじゃなかったの?・・・ええまあそうなんですが、いきなり17バイト版を書くのはハードルが高いので、最初はこれでよしとしてください。 |
| + | ---- |
| + | -次はcharsをやってみましょう。 |
| + | ; ex0001.nas |
| + | [FORMAT "WCOFF"] |
| + | [FILE "ex0001.nas"] |
| + | [INSTRSET "i486p"] |
| + | [BITS 32] |
| + | GLOBAL _G01Main |
| + | |
| + | [SECTION .text] |
| + | |
| + | _G01Main: |
| + | MOV AL,0x20 |
| + | putcloop: |
| + | CALL [ESI] |
| + | DB 0x55, 0x16, 0xb8 ; [5 (0) !5 1 AL] |
| + | INC AL |
| + | CMP AL,0x7f |
| + | JB putcloop |
| + | RET |
| + | |
| + | -Makefileはex0000.nasとほぼ同じなので省略しますね。これをmakeすると、45バイトのex0001.orgができます。やはり13バイトには遠く及ばないのですが、しかしCで書いたらこんなものではすまないので、アセンブラの優位性はしっかりと示されています。helloよりも小さくなったのは、やっぱり.dataセクションを作らないで済んでいるからというのが大きいです。 |
| + | ---- |
| + | -ということで、helloも.dataセクションなしで書いてみることにします。 |
| + | ; ex0002.nas |
| + | [FORMAT "WCOFF"] |
| + | [FILE "ex0002.nas"] |
| + | [INSTRSET "i486p"] |
| + | [BITS 32] |
| + | GLOBAL _G01Main |
| + | |
| + | [SECTION .text] |
| + | |
| + | _G01Main: |
| + | CALL [ESI] |
| + | DB 0x51, "hello, wolrd", 0 |
| + | RET |
| + | |
| + | -こんな風に書けば、ポインタ指定なしで直接データを置けるので、.dataセクションはいりません。 |
| + | -これをmakeすると、48バイトのex0002.orgができます。8バイトの減量ですね。 |
| + | ---- |
| + | -もっと小さくしたいということなら(まあ普通はそこまでやる必要はなくてex0000レベルで十分なのですが・・・というか「ぐいぐい01」でありさえすればC版でも十分)、20バイト以上ある標準のC向けのスターアップルーチンを使わないようにするという選択肢があります。これはリンカも使わないということです(リンカは勝手にスタートアップを使おうとするので)。難易度は結構高いです。.text以外のセクションを使っている場合は、これはやらないほうがいいでしょう。リンカなしで.dataセクションを扱うのは至難の業です。 |
| + | ; ex0003.nas |
| + | [FORMAT "BIN"] |
| + | [INSTRSET "i486p"] |
| + | [BITS 32] |
| + | |
| + | [SECTION .text] |
| + | |
| + | DB 0x47, 0x01, 0x04 ; 簡易形式用ヘッダ |
| + | |
| + | _G01Main: |
| + | CALL [ESI] |
| + | DB 0x51, "hello, wolrd", 0 |
| + | RET |
| + | |
| + | -こんな感じです。これはもうリンカとかは使わないので、Makefileなしでmakeします。 |
| + | efg01 ../z_tools/nask.g01 ex0003.nas ex0003.g01 ex0003.lst |
| + | -これで20バイトの.g01ができます。ついにきました。一気に「ぐいぐい01」らしいサイズです。 |
| + | ---- |
| + | -ここまできたらせっかくなので17バイトまで行きますかね(笑)。まず、.textの末尾のRETは省略できます。さらに簡易形式用ヘッダの最後の4のところに1を足して5にしておけば、最初の CALL [ESI] を省略できます。 |
| + | ; ex0004.nas |
| + | [FORMAT "BIN"] |
| + | [INSTRSET "i486p"] |
| + | [BITS 32] |
| + | |
| + | [SECTION .text] |
| + | |
| + | DB 0x47, 0x01, 0x05 ; 簡易形式用ヘッダ |
| + | |
| + | _G01Main: |
| + | DB 0x51, "hello, wolrd", 0 |
| + | |
| + | -これで完成です。これをnaskするとめでたく17バイトになります。・・・こんなDBしかないプログラムであれば、バイナリエディタだけで作ったほうが早いですけどね。 |
| + | * こめんと欄 [#s178e662] |
| + | - abcdw009向けの記述に修正。 -- [[K]] &new{2009-01-03 (土) 19:52:47}; |
| + | - abcdw014向けの記述に修正。 -- ''K'' &new{2009-01-15 (木) 19:30:35}; |
| | | |
| #comment | | #comment |