Hello, world!

http://d.hatena.ne.jp/shinichiro_h/20061113
明日SEA & FSIJ 合同フォーラムを聴講しに行く予定です。
最小Hello worldだけど、Windowsでメッセージボックスを出力するものだと何バイトなんだろうか。(Windowsの場合、メッセージボックスの方がコンソール出力より小さい)
http://piza2.2ch.net/tech/kako/979/979635776.htmlのレス270以下で、まずは512バイトに壁があるっぽい。
VC++6.0だと、WinMainで

  MessageBox( NULL, "Hello, world!", NULL, MB_OK );
return 0;
だけするのが32KB。
WinMainはCランタイムの初期化ルーチンであるWinMainCRTStartupから呼び出されていて、MessageBoxだけならCランタイムは不要だから、デフォルトライブラリを無視するようにして
#define NULL 0
#define MB_OK 0
__declspec(dllimport) int __stdcall MessageBoxA(void *hWnd, const char *lpText, const char *lpCaption, unsigned int uType);
void WinMainCRTStartup(void)
{
MessageBoxA( NULL, "Hello, world!", NULL, MB_OK );
}
こうすると16KBになった。
次に、文字列を.dataではなく.rdataに配置するように、コンパイルオプション/GFを追加したら12KBになった。
でもって、セクションの4KB境界をなくすために/OPT:NOWIN98を追加したら、2KBになった。
そして、リンカオプションに/merge:.rdata=.textを追加して.rdataを.textに追いやったら1024バイトになった。
http://pc8.2ch.net/test/read.cgi/tech/1148402614/のレス413で言っているのはこれだと思う。
この状態でも2000/XPでは実行できるけど、NOWIN98というからには、Windows 95/98では動かないのかも。
インポートセクション(.idata)は特殊なので、明示的に.textにはマージできなさそう。
※ リンカオプションで/merge:.idata...をするとおかしなことになるけど、リンカが.idataを.textにマージしてくれるようで、生成されたバイナリには.textセクションしかない。
この先は手作業で削らないといけないっぽい。PEファイルは先頭がMZじゃないといけないし、ELFより断然デカイ。
ざっとレスを読んだ感じだと、実行ファイルからインポートセクションをなくすのがキモで、そのために、書き込める領域に対して実行時にインポートセクションを作成して、何らかの方法でそのインポートセクションを有効にするみたい。
kernel32.dllは必ずロードされているはずなので、それを使うのかな。