Ответ 1
Основная причина, по которой при стандартных настройках вы не можете сделать небольшой инструмент, так это то, что в ваш двоичный файл вставляется множество символов и ссылок на стандартные библиотеки. Вы должны быть явным, чтобы удалить даже этот базовый материал.
Вот как я это сделал:
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.