Оптимизация выходного файла в Microsoft Visual C++.
Параметры линкера для уменьшения размера:
- объединение секций
Код:
/MERGE:.data=.text /MERGE:.rdata=.text
- можно еще снизить выравнивание, например, задать 512 байт или 32 байта
или
соответственно.
- смена точки входа
или
для консольного и виндового приложения соответственно. Уменьшает размер, т.к. тогда линкер не пихает в экзешник код стартовой функции mainCRTStartup (WinMainCRTStartup). Только надо помнить, что параметры main (WinMain) в этом случае не будут нести никакого смысла, аргументы командной строки придется получать явно через API GetCommandLine().
- еще можно убрать нафиг CRT или линковать ее динамически:
Код:
/NODEFAULTLIB msvcrt.lib
С учетом всех рекомендаций:
Код:
#include <windows.h>
#pragma comment(linker, "/NODEFAULTLIB /MERGE:.data=.text /MERGE:.rdata=.text /ALIGN:512 /ENTRY:WinMain")
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
MessageBox(0, "Hello, World!", "Tiny application", MB_ICONINFORMATION);
return 0;
}
Результат - имеет хелловорлд размером 1к, состоящим из заголовка экзешника и одной секции.
Дизассемблерный листинг точки входа не содержит ни одного лишнего байта:
Код:
00400230 >/$ 55 PUSH EBP
00400231 |. 8BEC MOV EBP,ESP
00400233 |. 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00400235 |. 68 08024000 PUSH tiny.00400208 ; |Title = "Tiny application"
0040023A |. 68 1C024000 PUSH tiny.0040021C ; |Text = "Hello, World!"
0040023F |. 6A 00 PUSH 0 ; |hOwner = NULL
00400241 |. FF15 00024000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00400247 |. 33C0 XOR EAX,EAX
00400249 |. 5D POP EBP
0040024A \. C2 1000 RETN 10
UPD: Можно снизить выравнивание до 16-и байт, притворившись, что мы собираем драйвер:
/ALIGN:16 /DRIVER
это нужно вписать в настройки проекта, в #pragma comment(linker) это не прокатит