информационная безопасность
без паники и всерьез
 подробно о проекте
Rambler's Top100Где водятся OGRыСтрашный баг в WindowsСетевые кракеры и правда о деле Левина
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Microsoft обещает радикально усилить... 
 Ядро Linux избавляется от российских... 
 20 лет Ubuntu 
главная обзор 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)

[11549]



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



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