使用标准设置无法制作小工具的主要原因是大量符号和对标准库的引用被拉入二进制文件。你必须明确地删除那些基本的东西。
我是这样做的:
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
代码:
您可能需要进行很多调整和反复试验。有时,循环给出更小的代码,有时是调用,有时是强制内联函数。例如,在我的代码中,我没有一个包含所有花哨多态样式的火焰变换的干净链表,而是有一个固定数组,其中每个元素都是一个包含所有参数(使用或未使用)的大实体,作为所有火焰的联合根据 Scott Draves 火焰纸。
您的技巧不会是可移植的,其他版本的 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。