ページへ戻る

− Links

 印刷 

GUIGUI01​/man0005 のバックアップソース(No.2) :: OSASK計画

osaskwiki:GUIGUI01/man0005 のバックアップソース(No.2)

« Prev[4]  Next »[5]
* 「ぐいぐい01」のアプリフォーマット
-(by [[K]], 2008.12.29)
*** 註
-所詮はOSASK-HB向けなのでまあ暫定的なものです。とりあえず2008.12.29時点で最新定のabcdw007での仕様を書きました。ちなみにabcdw008でもこの仕様のままの予定です。
-旧仕様については[[GUIGUI01/man0003]]に記述が残してあります。見比べると分かりますが、実はほとんど変わっていません。
*** 基本構造
-最初の2バイトがシグネチャで、0x47 0x01。
--大文字小文字アルファベット+0x00~0x1fの組み合わせは他でも使うかもしれないので、誰かがもし下記に似たフォーマットを独自に設計して利用するつもりなら避けてもらえると個人的にはありがたい。
-その次はトップレベルのタグ総数。
--この値が0だと小プログラム向け簡易形式になる。1以上なら通常形式。簡易形式ではgh4によるフラグが後続し(これは通常形式のトップレベルタグ[03]で記述される内容)、その後はバイト単位でのアラインの後、ファイル終端まですべてコードセクションのイメージと見なされる。簡易形式ではデータセクションやリロケーション情報、スタックサイズ指定なども一切できない。
-それ以降はすべてタグ。
-数値はたいてい[[GUIGUI01/man0004]]の(1)の方法でエンコードされている。以下これをgh4エンコードと呼ぶ。
----
-(例)helloc.g01 (いわゆるC言語で書いた69バイトの"hello, world\n")
 47 01 28 D3 09 4C 54 89 35 10 00 00 00 E9 15 00
 00 00 31 FF 8B 35 10 00 00 00 FF 26 55 BA 00 00
 00 00 89 E5 57 56 E8 0B 00 00 00 50 32 30 5E 5F
 5D 99 41 28 94 8D 20 94 98 68 65 6C 6C 6F 2C 20
 77 6F 72 6C 64

 47 01 -- シグネチャ。
 2_    -- トップレベルタグ数2(この場合は[0D]が2個)。
 _8 D3 -- [0D] セクション開始タグ、ネスト内タグ数3。
   0_       -- [00] NOPなタグ。
   _9 4C 54 -- [14] イメージ展開タグ、イメージ長 0x54 = 84。つまり42バイト。
     89 35 10 ... 5E 5F 5D -- コードセクションの中身。実際にはこの直後にC3の1バイトも足される。
   99 4_    -- [19] コンパクト型リロケーション情報。要素数4。
    _1 28 94  -- リロケーション情報の中身。10進数で書けば、 { 1 2 9 4 }。
                   これを翻訳すれば、コードセクションのオフセット 0x02, 0x0f, 0x17 バイト目
                   からの4バイトの値に実際のデータセクションの開始アドレスを加算する。
 8D 2_ -- [0D] セクション開始タグ、ネスト内タグ数2。
   _0       -- [00] NOPなタグ。
   94 98    -- [14] イメージ展開タグ、イメージ長 0x18 = 24。つまり12バイト。
     68 65 6C ... 72 6C 64 -- データセクションの中身。実際にはこの直後に00が32バイト追加される。

-(例)hello.g01 (いわゆる18バイトの"hello, world\n")
 47 01 01 50 13 68 65 6C 6C 6F 2C 20 77 6F 72 6C
 64 00

 47 01 -- シグネチャ。
 2_    -- トップレベルタグ数0。つまり簡易形式。
 _1    -- フラグ1。つまり、CALL([ESI]);の自動挿入あり、自動改行有効、rjcあり、初期値テーブルなし。
   50 13 68 ... 6C 64 00 -- コードセクションの中身。実際にはこの前に FF 16 の2バイトが追加され、
                              末尾にC3の1バイトも足される。

*** タグのフォーマット
-タグ番号はすべてgh4でエンコード。このルールはネスト内のタグでも有効。
-[00] :
--後続パラメータなし。
-[01]~[0B] :
--何らかの数値を指定。後続パラメータは1つで、gh4でエンコード。
-[0C]~[0F] :
--ネスト構造型タグ。タグの中にタグが複数含まれるタグ(0や1つの場合もあるが)。まず一つのパラメータがgh4で記述され、それがネスト内に含まれるタグの数を表す。
--ネストの中にネストのタグが含まれることも当然ありうるが、その場合はネスト全体でタグ数1と数える。上記の例を参照のこと。
-[10]~[17] :
--4bit数値による一次元配列記述用タグ。gh4ではないエンコードのビット列などを格納するために使われている。まず一つのパラメータがgh4で記述され、それがこのタグ内に含まれるバイナリの長さを表す。ただしこの長さはバイト単位でもビット単位でもなく、4bit単位である。
-[18]~[1F] :
--gh4による一次元配列記述用タグ。gh4でエンコードされた数値列を格納するために使われている。まず一つのパラメータがgh4で記述され、それがこのタグ内に含まれるgh4数値の個数を表す。
-[20]~[27] :
--[10]~[17]の形式の配列記述用タグ。たとえば可変長文字列の配列などを記述するために使う。
--最初にgh4があって、これが文字列の個数に相当。そしてその個数の回数だけ「各文字列長に相当するgh4と文字列そのものに相当する4bit配列」を繰り返す。
-[28]以降のタグ番号については、どんなフォーマットを取るかの規定はまだない。
*** タグのコード(ルート内)
-[00] 何もしない。NOPなタグ。パディングなどで使いたければ使う。
----
-[01] フォーマットタイプ規定。
--以降のフォーマットを指定するタグ。しかしたいてい省略される(サイズがもったいないので)。このタグが省略されているときは、「ぐいぐい01」仕様のIA-32アプリ(=フォーマット番号1)。このタグで1以外のパラメータが来た場合は他のフォーマットを指定している可能性があるので以降のタグの解釈をやめて実行をするべきではない。
--なおタグ番号[03]以上のタグが一度でも表れた後にこのタグが出てくる可能性はない。もし万一そんなことがあればそこから先は解釈する必要がない。
-[02] リザーブ。
-[03] 各種フラグ類の指定。
--bit0がCALL([ESI]);の自動挿入フラグ(これが1だとコードセクションの最初に FF 16 の2バイトが追加される)。
--bit1が自動改行禁止(これが1だとアプリ終了時にコンソール出力の最後が'\n'でなかったとしても、特に何もしない。0ならこういう場合は'\n'を追加出力してから終了する)。
--bit2がrjcなし(これが1だとrjcがかかっていないことを示す)。
--bit3-4が初期値テーブル。0なら初期値テーブルなし。1ならEAXの初期値テーブルあり。2ならEAXとECXの初期値テーブルあり。3ならフルセット仕様の初期値テーブルあり。
--このタグを省略すると0を指定したものと見なされる。
-[04] スタックサイズの指定(指数部)。
--このタグを見つけると自動的に仮数部のデフォルトが1に設定される。したがって仮数部も指定するときは、先にこのタグで指数部を指定してからにする。0で4KB単位(=スタックサイズ=仮数部×4KB)、1で16KB単位、2で64KB単位、3で256KB単位、以下省略。
--スタックについて全く指定がない場合、デフォルトの設定が使われる。デフォルトでは、指数部=4KB、仮数部=256。つまり1MB。
-[05] スタックサイズの指定(仮数部)。(指定された値+1)が仮数部になる。
-[06] リザーブ。
-[07] リザーブ。
-[08] リザーブ(malloc領域はbss内にとればよい)。
-[09] リザーブ。
-[0A] メモリマップトファイル用の領域のサイズ指定(指数部)。指定方法はスタックサイズと同じ。
--デフォルトは、指数部=4KB、仮数部=256。つまり1MB。
-[0B] メモリマップトファイル用の領域のサイズ指定(仮数部)。指定方法はスタックサイズと同じ。
----
-[0C] コメントタグ。このタグ内の記述はすべて無視する。
--コメント用タグが何種類もあるのは、バイナリエディタでちょっとタグをコメントアウトしたいときのため。それぞれのフォーマットタイプにコメント形式がある。
--[01]~[0B]の形式のコメントは原則として用意しない。これは [00] [00] に書き換えることでコメントアウトできるから。・・・むろん複雑な構造のタグも全部[00]で埋め尽くすことでもコメントアウトはできるが、修正箇所が多くて大変だろうと思うので、それぞれにコメント形式がある。
--もちろんコメントアウトのみならず、構造を持ったコメントとして使うこともできる。いずれにせよ、「ぐいぐい01」ローダはこれらを無条件に読み飛ばす。そして[01]~[0B]の形式のコメントはこの用途でも使い道がないと考えているので用意していない(数値一つをただ置けるだけではコメントとして記述力がなさ過ぎる)。
-[0D] セクション記述タグ。下記参照。
----
-[18] コメントタグ。このタグ内の記述はすべて無視する。
-上記以外はリザーブ。
*** タグのコード(セクション記述タグ内)
-[00] 何もしない、NOPなタグ。パディングなどで使いたければ使う。
----
-[01] セクションタイプ指定。
--このタグの指定がない場合、最初に記述されたセクションならセクションタイプ0がデフォルト。以前にセクション記述タグがあった場合は、(直前のセクションタイプ+1)がデフォルト。
-[02] アライン指定タグ。デフォルトのアラインは4KB。
-[04] これはセクションタイプによって意味が異なる。
--コードセクション(セクションタイプ0)の場合は、エントリポイントの指定。デフォルトはゼロ。
--bssセクション(セクションタイプ2)の場合は、セクションサイズ(仮数部)の指定。
---スタックなどとは違って+1はない。デフォルトでは0。指数部のデフォルトは1バイト。
----
-[0C] コメントタグ。このタグ内の記述はすべて無視する。
----
-[14] セクションイメージタグ。バイナリデータをそのまま記述。なお、コードセクションは必ず末尾に1バイトのC3が付与されるし、データセクションには必ず末尾に32バイトの00が付与される。コードセクションは、フラグの値によっては、 FF 16 も先頭に挿入される。これらの挿入されるバイト数は、イメージのサイズには含まれない。
----
-[18] コメントタグ。このタグ内の記述はすべて無視する。
-[19] コンパクト型リロケーション情報。これを配置するときは必ず[14]の後になる(直後である必要はない)。
--このリロケーションアルゴリズムは、バイナリの指定したオフセットからの4バイトに対して、指定したセクションの開始アドレスの値をリトルエンディアンで加えるというただそれだけのことをする。
//--[19]ではeh4の配列になっているわけだが、最初の要素は「*どの*セクションの開始アドレスを加算するか」である。残りの要素が、補正の必要なオフセットの羅列になっているのだが、これはコンパクト化のための細工がある。まず補正が必要なオフセットをすべて並べて、これをソートして昇順にする。そしてデータセクションへのリンク情報の場合、オフセットを全部4で割る(つまりデータセクション内のアドレス情報はすべてアラインされていると仮定している・・・これに適合しない場合は[1A]のリロケーション情報を使う)。さらにオフセット列の最初の要素以外は前の値からの増分値のみをeh4にして並べる。 -- commented_out by K, 2008.11.19
--[19]ではgh4の配列になっているわけだが、最初の要素は「*どの*セクションの開始アドレスを加算するか」である。残りの要素が、補正の必要なオフセットの羅列になっているのだが、これはコンパクト化のための細工がある。まず補正が必要なオフセットをすべて並べて、これをソートして昇順にする。そしてデータセクションへのリンク情報の場合、オフセットを全部4で割る(つまりデータセクション内のアドレス情報はすべてアラインされていると仮定している・・・これに適合しない場合は[1A]のリロケーション情報を使う)。さらにオフセット列の最初の要素以外は前の値+4からの増分値のみをgh4にして並べる(データセクションの場合は前の値+1からの増分値)。
--一つのセクションに対して、コードセクションとデータセクションの両方の補正が必要になることももちろんありうる。その場合は、[19]のタグが2回現れることとなる。bssセクションのアドレスも参照する場合は3回現れることもありえるだろう。
-[1A] コンパクトではないリロケーション情報。フォーマットの詳細はまだ決めていない。
----
-上記以外はすべてリザーブ。

« Prev[4]  Next »[5]