標準設定では小さなツールを作成できない主な理由は、多くのシンボルと標準ライブラリへの参照がバイナリに取り込まれるためです。その基本的なものでさえも削除するには、明示的にする必要があります。
これが私がそれをした方法です:
http://phresnel.org/gpl/4k/ntropy2k7/
関連するオプション:
主に自明:
gcc main.c -o fourk0001 -Os -mfpmath=387 \
-mfancy-math-387 -fmerge-all-constants -fsingle-precision-constant \
-fno-math-errno -Wall -ldl -ffast-math -nostartfiles -nostdlib \
-fno-unroll-loops -fshort-double
マッサージ:
strip
バイナリに埋め込まれている不要なシンボルを取り除くのに役立ちます。
strip -R .note -R .comment -R .eh_frame -R .eh_frame_hdr -s fourk0001
コード:
微調整と試行錯誤が必要になる場合があります。ループによって小さなコードが生成されることもあれば、呼び出しが行われることもあり、強制的にインライン化される関数が生成されることもあります。私のコードでは、たとえば、派手な多形スタイルのすべての炎の変換を含むクリーンなリンクリストを作成する代わりに、各要素が、すべての炎の結合として、使用済みまたは未使用のすべてのパラメーターを含む大きなエンティティである固定配列を使用しています。スコット・ドレイブスの炎の紙による。
あなたのトリックは移植性がありません、他のバージョンのg++は次善の結果を与えるかもしれません。
上記のパラメーターを使用して、関数を作成するのmain()
ではなく、関数を作成することに注意してください_start()
。
また、ライブラリの使用は少し異なることに注意してください。SDLと標準ライブラリ関数を上品で便利な方法でリンクする代わりに、手動でリンクする必要があります。例えば
void *libSDL = dlopen( "libSDL.so", RTLD_LAZY );
void *libC = dlopen( "libc.so", RTLD_LAZY );
#if 1
SDL_SetVideoMode_t sym_SDL_SetVideoMode = dlsym(libSDL, "SDL_SetVideoMode");
g_sdlbuff = sym_SDL_SetVideoMode(WIDTH,HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
#else
((SDL_SetVideoMode_t)dlsym(libSDL, "SDL_SetVideoMode"))(WIDTH,HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
#endif
//> need malloc, probably kinda craft (we only use it once :| )
//> load some sdl cruft (cruft!)
malloc_t sym_malloc = dlsym( libC, "malloc" );
sym_rand = dlsym( libC, "rand" );
sym_srand = dlsym( libC, "srand" );
sym_SDL_Flip = dlsym(libSDL, "SDL_Flip");
sym_SDL_LockSurface = dlsym(libSDL, "SDL_LockSurface");
sym_SDL_UnlockSurface = dlsym(libSDL, "SDL_UnlockSurface");
sym_SDL_MapRGB = dlsym(libSDL, "SDL_MapRGB");
また、アセンブラに害を及ぼす必要はありませんが、コードによってUBが生成される可能性があります。
編集:
おっと、私は組み立てについて嘘をついた。
void _start() {
...
asm( "int $0x80" :: "a"(1), "b"(42) );
}
これにより、プログラムは42を返します。