ページへ戻る

− Links

 印刷 

GUIGUI01​/memo18 のバックアップ差分(No.2) :: OSASK計画

osaskwiki:GUIGUI01/memo18 のバックアップ差分(No.2)

« Prev[4]  Next »[5]
1: 2008-12-30 (火) 11:02:59 ソース[6] 2: 2008-12-30 (火) 12:24:30 ソース[7]
Line 3: Line 3:
-メモのうち重要な部分をそのうちまとめてまともなページを作る -メモのうち重要な部分をそのうちまとめてまともなページを作る
*** (33) naskで「ぐいぐい01」アプリを作る *** (33) naskで「ぐいぐい01」アプリを作る
--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      0x50, 0x30, 0x30    ; [5 0 (!6_x) 3 EAX] [3] ; 5 0 (!6_x) 3 の後に(!6_0)がある
 +         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すると、77バイトのex0000.g01と57バイトのex0000.orgができるはずです。77バイトってC版(69バイト)よりも大きいじゃないか!と思うかもしれませんが、77バイトはtek5をかけた場合の大きさで、tek5しなければ57バイトなのです。つまり、.g01のほうは無視して、.orgのほうを使いましょう(.g01を消して.orgを.g01と改名してもいいです)。
 +-57バイトってどういうこと!?18バイトになるんじゃなかったの?・・・ええまあそうなんですが、いきなり18バイト版を書くのはハードルが高いので、最初はこれでよしとしてください。
 +----
 +-次はcharsをやってみましょう。
 + ; ex0001.nas
 + [FORMAT "WCOFF"]
 + [FILE "ex0001.nas"]
 + [INSTRSET "i486p"]
 + [BITS 32]
 +         GLOBAL  _G01Main
 +
 + [SECTION .text]
 +
 + _G01Main:
 +         MOV      AL,0x20
 + putcloop:
 +         CALL    [ESI]
 +         DB      0x50, 0x51, 0x61, 0x03    ; [5 0 !5 1 AL] [3]
 +         INC      AL
 +         CMP      AL,0x7f
 +         JB      putcloop
 +         RET
 +
 +-Makefileはex0000.nasとほぼ同じなので省略しますね。これをmakeすると、46バイトのex0001.orgができます。やはり14バイトには遠く及ばないのですが、しかしCで書いたらこんなものではすまないので、アセンブラの優位性はしっかりと示されています。helloよりも小さくなったのは、やっぱり.dataセクションを作らないで済んでいるからというのが大きいです。
 +----
 +-ということで、helloも.dataセクションなしで書いてみることにします。
 + ; ex0002.nas
 + [FORMAT "WCOFF"]
 + [FILE "ex0002.nas"]
 + [INSTRSET "i486p"]
 + [BITS 32]
 +         GLOBAL  _G01Main
 +
 + [SECTION .text]
 +
 + _G01Main:
 +         CALL    [ESI]
 +         DB      0x50, 0x10, "hello, wolrd", 0, 0x30
 +         RET
 +
 +-こんな風に書けば、ポインタ指定なしで直接データを置けるので、.dataセクションはいりません。
 +-これをmakeすると、50バイトのex0002.orgができます。7バイトの減量ですね。
 +----
 +-もっと小さくしたいということなら(まあ普通はそこまでやる必要はなくて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      0x50, 0x10, "hello, wolrd", 0, 0x30
 +         RET
 +
 +-こんな感じです。これはもうリンカとかは使わないので、Makefileなしでmakeします。
 + efg01 ../z_tools/nask.g01 ex0003.nas ex0003.g01 ex0003.lst
 +-これで22バイトの.g01ができます。ついにきました。一気に「ぐいぐい01」らしいサイズです。
 +----
 +-ここまできたらせっかくなので18バイトまで行きますかね(笑)。まず、.textの末尾のRETは省略できます。また、APIパケットは今、 [5 0 1 "hello, wolrd" 0] [3] になっているのですが、この最後の4bitの3を、1の後の「隙間の埋め用」の0のところに入れてもいい事になっています。さらに簡易形式用ヘッダの最後の4のところに1を足して5にしておけば、最初の CALL [ESI] を省略できます。
 + ; ex0004.nas
 + [FORMAT "BIN"]
 + [INSTRSET "i486p"]
 + [BITS 32]
 +
 + [SECTION .text]
 +
 +         DB      0x47, 0x01, 0x05  ; 簡易形式用ヘッダ
 +
 + _G01Main:
 +         DB      0x50, 0x13, "hello, wolrd", 0
 +
 +-これで完成です。これをnaskするとめでたく18バイトになります。・・・こんなDBしかないプログラムであれば、バイナリエディタだけで作ったほうが早いですけどね。
* こめんと欄 * こめんと欄
#comment #comment
« Prev[4]  Next »[5]