информационная безопасность
без паники и всерьез
 подробно о проекте
Rambler's Top100Где водятся OGRыSpanning Tree Protocol: недокументированное применение
BugTraq.Ru
Русский BugTraq
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Модель надежности отказоустойчивой... 
 NSA выпустило Гидру 
 Неприятная уязвимость во всех WinRAR,... 
 Apple случайно превратила FaceTime... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / FAQ / программирование
FAQ
главная
операционные системы
sysadmin
программирование
теория
общие вопросы





Без статической RTL размер файла получается 16 Кб. Как сделать его еще меньше?
:-)
Опубликовано: dl, 25.12.03 14:30

Можно уменьшить выравнивание секций в файле и/или объединить секции.

Как правило, компиляторы создают в исполняемом файле отдельные секции для кода, данных, таблицы импорта и т.д. Для компилятора MSVC эти секции называются соответственно .text, .data, .rdata.

Каждая секция в файле дополняется нулями, чтобы ее размер был кратен некоторому значению, которое называется выравниванием файла и представляет из себя число 2n. Выравнивание файла задается опцией линкера /FILEALIGN.

Минимальное выравнивание, при котором программа будет запускаться, составляет 512 байт (размер сектора диска). Visual C++ до версии 6.0 выравнивал секции по данному минимальному значению, но начиная с версии 6.0 линкер по умолчанию выравнивает секции по границе 4 Kб (размер страницы памяти на x86). Таким образом несколько увеличивается скорость загрузки файла на Windows 9x, но при этом увеличивается и размер файла.

Вернуться к старому поведению линкера позволяет опция /OPT:NOWIN98 (она эквивалентна опции /FILEALIGN:512)

С помощью ключа /MERGE можно объединить секции. Например, в нижеприведенной программе все секции объединяются в одну секцию .text, для которой устанавливаются атрибуты ERW (Execute, Read, Write), при этом игнорируется соответствующее предупреждение линкера.

Кстати, указания линкеру удобно давать прямо в тексте программы директивой #pragma.


// small.cpp
#include <windows.h>

#pragma comment(linker, "/MERGE:.rdata=.text")
#pragma comment(linker, "/MERGE:.data=.text")
#pragma comment(linker, "/FILEALIGN:512 /SECTION:.text,ERW /IGNORE:4078")
#pragma comment(linker, "/ENTRY:New_WinMain")
#pragma comment(linker, "/NODEFAULTLIB")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")

void New_WinMain()
{
MessageBox(NULL, "Hello from a tiny program!", "Bugtraq FAQ", MB_OK);
}

---
При компиляция данной программы командой
cl small.cpp user32.lib
получается файл small.exe размером 1024 байта.

В принципе, линкер позволяет задать /FILEALIGN:32 и размер файла получится 672 байта. Но только запускаться этот файл не будет. Видимо, 1024 байта – это предел.

Следует отметить, что иногда объединение секций нецелесообразно. Например, если в программе используется большой глобальный массив типа char Buf[100000]. Если секции не объединять, то данный массив будет размещаться в секции неинициализированных данных и реально не будет присутствовать в исполняемом файле. Если же все секции объединить, то неинициализированные данные станут инициализированными и размер файла увеличится примерно на 100 Кб.



обсудить  |  все отзывы (0)

[8830]



Rambler's Top100
Рейтинг@Mail.ru



  Copyright © 2001-2019 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach