- まず、ベースとなるソースプログラムを提示します。
int uxfdl_printf(const char *fmt, ...);
int entry(int argc, const char **argv)
{
uxfdl_printf("hello\n");
return 0;
}
- たったこれだけの128バイトのプログラムです。
- これをgcc 3.4.5で普通にコンパイルすると(=リンクはしない)、以下の500バイトのCOFFファイルが得られます。
offset +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
---------------------------------------------------------------------------
00000000 4C 01 04 00 00 00 00 00 F8 00 00 00 0D 00 00 00 L...............
00000010 00 00 04 01 2E 74 65 78 74 00 00 00 00 00 00 00 .....text.......
00000020 00 00 00 00 20 00 00 00 B4 00 00 00 E4 00 00 00 .... ...........
00000030 00 00 00 00 02 00 00 00 20 00 00 60 2E 64 61 74 ........ ..`.dat
00000040 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a...............
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060 40 00 00 C0 2E 62 73 73 00 00 00 00 00 00 00 00 @....bss........
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080 00 00 00 00 00 00 00 00 80 00 00 C0 2E 72 64 61 .............rda
00000090 74 61 00 00 00 00 00 00 00 00 00 00 10 00 00 00 ta..............
000000A0 D4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000B0 40 00 00 40 55 89 E5 68 00 00 00 00 E8 00 00 00 @..@U..h........
000000C0 00 C9 31 C0 C3 90 90 90 90 90 90 90 90 90 90 90 ..1.............
000000D0 90 90 90 90 68 65 6C 6C 6F 0A 00 00 00 00 00 00 ....hello.......
000000E0 00 00 00 00 04 00 00 00 0A 00 00 00 06 00 09 00 ................
000000F0 00 00 0C 00 00 00 14 00 2E 66 69 6C 65 00 00 00 .........file...
00000100 00 00 00 00 FE FF 00 00 67 01 68 65 6C 6C 6F 2E ........g.hello.
00000110 63 00 00 00 00 00 00 00 00 00 00 00 5F 65 6E 74 c..........._ent
00000120 72 79 00 00 00 00 00 00 01 00 20 00 02 01 00 00 ry........ .....
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140 2E 74 65 78 74 00 00 00 00 00 00 00 01 00 00 00 .text...........
00000150 03 01 11 00 00 00 02 00 00 00 00 00 00 00 00 00 ................
00000160 00 00 00 00 2E 64 61 74 61 00 00 00 00 00 00 00 .....data.......
00000170 02 00 00 00 03 01 00 00 00 00 00 00 00 00 00 00 ................
00000180 00 00 00 00 00 00 00 00 2E 62 73 73 00 00 00 00 .........bss....
00000190 00 00 00 00 03 00 00 00 03 01 00 00 00 00 00 00 ................
000001A0 00 00 00 00 00 00 00 00 00 00 00 00 2E 72 64 61 .............rda
000001B0 74 61 00 00 00 00 00 00 04 00 00 00 03 01 07 00 ta..............
000001C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001D0 00 00 00 00 04 00 00 00 00 00 00 00 00 00 20 00 .............. .
000001E0 02 00 12 00 00 00 5F 75 78 66 64 6C 5F 70 72 69 ......_uxfdl_pri
000001F0 6E 74 66 00 ntf.
- 128バイトから500バイトになるなんて!
- 中身は見ての通りゼロばかりでスカスカです。
- この中には32バイトの.textセクションと、0バイトの.dataセクションと16バイトの.rdataセクションと0バイトの.bssセクションがあります。
- 128バイトのソースから作るからスカスカなんだという反論は可能で、だからもっと長いソースから作ればスカスカ率は改善するかもしれないです。
- 手元にあるobj2uxf.cのコンパイルで実験したところ、15.9KBのソースに対して6.52KBのCOFFファイルでした。
- こうなった原因の一つに、asがあまり優秀ではないということがあります。無駄なパディングが多すぎるのです。これはasがダメなのであって、COFFの仕様のせいではないです。
- というこで、gccにアセンブラソースを出力させて、gas2naskを使ってnask向けソースに変換し、objを作ってみました。
offset +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
---------------------------------------------------------------------------
00000000 4C 01 03 00 00 00 00 00 B8 00 00 00 0A 00 00 00 L...............
00000010 00 00 00 00 2E 74 65 78 74 00 00 00 00 00 00 00 .....text.......
00000020 00 00 00 00 11 00 00 00 93 00 00 00 A4 00 00 00 ................
00000030 00 00 00 00 02 00 00 00 20 00 10 60 2E 64 61 74 ........ ..`.dat
00000040 61 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 a...............
00000050 8C 00 00 00 A4 00 00 00 00 00 00 00 00 00 00 00 ................
00000060 40 00 30 C0 2E 62 73 73 00 00 00 00 00 00 00 00 @.0..bss........
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080 00 00 00 00 00 00 00 00 80 00 10 C0 68 65 6C 6C ............hell
00000090 6F 0A 00 55 89 E5 68 00 00 00 00 E8 00 00 00 00 o..U..h.........
000000A0 C9 31 C0 C3 04 00 00 00 04 00 00 00 06 00 09 00 .1..............
000000B0 00 00 08 00 00 00 14 00 2E 66 69 6C 65 00 00 00 .........file...
000000C0 00 00 00 00 FE FF 00 00 67 01 68 65 6C 6C 6F 2E ........g.hello.
000000D0 63 00 00 00 00 00 00 00 00 00 00 00 2E 74 65 78 c............tex
000000E0 74 00 00 00 00 00 00 00 01 00 00 00 03 01 11 00 t...............
000000F0 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100 2E 64 61 74 61 00 00 00 00 00 00 00 02 00 00 00 .data...........
00000110 03 01 07 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120 00 00 00 00 2E 62 73 73 00 00 00 00 00 00 00 00 .....bss........
00000130 03 00 00 00 03 01 00 00 00 00 00 00 00 00 00 00 ................
00000140 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 ................
00000150 00 00 00 00 00 00 00 00 02 00 5F 65 6E 74 72 79 .........._entry
00000160 00 00 00 00 00 00 01 00 00 00 02 00 12 00 00 00 ................
00000170 5F 75 78 66 64 6C 5F 70 72 69 6E 74 66 00 _uxfdl_printf.
- 128バイトが382バイトになりました。でもまあスカスカ感はあまり変わりません。
- .textセクションが17バイトに、.dataセクションが7バイトになりました。.bssは0ですが、.rdataはありません(naskでは.rdataに対応しておらず、すべて.dataに読み替えられます)。
- これをuxfに変換するとこうなります。
offset +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
---------------------------------------------------------------------------
00000000 01 00 11 07 00 55 89 E5 68 00 00 00 00 E8 00 00 .....U..h.......
00000010 00 00 C9 31 C0 C3 02 01 11 07 19 70 72 69 6E 74 ...1.......print
00000020 66 68 65 6C 6C 6F 0A 00 00 fhello...
- 超スッキリです!41バイトです。しかも最初の11,07,00で、.text、.data、 .bssのサイズがすぐにわかります。
- uxfでは_uxfdl_で始まるラベルについては、_uxfdl_が省略されて格納されます。
- uxfdlというのはuxfのダイナミックリンクという意味です。