Маленький размер проги
Вообщем какой тип проекта выбрать, и что в настройках изменить ?
PS: размер одиночного *.ехе файла должен быть не больше 100кб. ВОоще такое возможно та ?
#---------------------------
#include <windows>
DWORD APIENTRY start(VOID){
return EXIT_SUCCESS;
}
#---------------------------
Размер от 496 байт. :)
В настройках проекта надо установить Linker -> Advanced -> Entry Point = "start" (/ENTRY:start). Если не использовать библиотеки вроде STL, ATL, MFC и т. д., то получится намного меньше 100 кб. :)
Минимальная (в принципе) прога получится из такого исходника:
#---------------------------
#include <windows>
DWORD APIENTRY start(VOID){
return EXIT_SUCCESS;
}
#---------------------------
Размер от 496 байт. :)
В настройках проекта надо установить Linker -> Advanced -> Entry Point = "start" (/ENTRY:start). Если не использовать библиотеки вроде STL, ATL, MFC и т. д., то получится намного меньше 100 кб. :)
Размер исполняемого файла PE не может быть меньше 1кб.
Кстати, зачем ты подключаешь windows.h ?
Да и для чего нужна такая программа? Программа должна что-то делать, хотя бы выводить "Hello world!", при этом она не превысила бы 1кб:
http://forum.codenet.ru/showthread.php?threadid=16213
Смотри статью здесь:
http://www.codenet.ru/progr/visualc/esmall.php
Я же сказал 496. Работает нормально, но, действительно, ничего не делает. :)
>> Кстати, зачем ты подключаешь windows.h ?
Можно и без .h, если С++... Любая прога под винду его использует, да и хуже от него не станет. ;)
>> Программа должна что-то делать, хотя бы выводить "Hello world!".
Тогда это будет уже не минимальная программа. :D Но всё равно очень маленькая, если использовать не printf или cout << "...", а WriteConsole или WriteFile.
Естественно, все эти выкрутасы имеет смысл делать только в маленьких прогах. Попробуй-ка напиши большую прогу, используя только WinAPI. :) Но эато так писать легче, чем на асме, а результат получается ничуть не хуже (в 99.9% случаев).
Я же сказал 496. Работает нормально, но, действительно, ничего не делает. :)
В Windows для стандартного загрузчика минимальная граница выравнивания секций - 512 байт.
Сл-но, минимальная программа с одной единственной секцией будет занимать 1кб: вначале PE-заголовок, потом выравненная на 512 байт секция кода. Секция должна быть кратна 512 байтам, иначе загрузчик будет ругаться. Итого 512 + 512 = 1кб.
Покажи ка свою программу с параметрами компиляции и линковки, а так же в собранном виде.
Можно и без .h, если С++... Любая прога под винду его использует, да и хуже от него не станет. ;)
Любая ли?
Хуже не станет... ты всегда руководствуешься таким принципом при программировании?
>> Программа должна что-то делать, хотя бы выводить "Hello world!".
Тогда это будет уже не минимальная программа. :D
Да ну...
Ты считаешь, что вывод на экран одной строки займет более 512 байт?
Естественно, все эти выкрутасы имеет смысл делать только в маленьких прогах. Попробуй-ка напиши большую прогу, используя только WinAPI. :)
Ты считаешь, что основное наполнение программ - это обертка Win32 API?
Нет, это не так.
Мы малость ушли от темы, но по теме тут и не говорят. :D
Поехали... Ладно, уберём нехороший windows.h
#------------- z.c ------------
unsigned __stdcall start(void){
return 0;
}
#------------------------------
MSC v13.10:
$ cl /Oxs z.c /link /entry:start /subsystem:windows /align:1
Получается работающий ехе-ник размером 467 байт.
Я не призываю всех писать и компилировать программы таким способом. Это всего лишь ради спортивного интереса...
$ cl /Oxs z.c /link /entry:start /subsystem:windows /align:1
Получается работающий ехе-ник размером 467 байт.
Хитрец... :D
В прошлом посте ты не указал /align:1.
Дело в том что этим параметром линковки ты принудительно определяешь границу выравнивания.
Ты перехитрил сам себя. Попробуй запустить свою "программу". Она не работает по причине того, что граница выравнивания, как я уже говорил, должна быть кратна 512.
В W9x выдается соответствующий диалог ошибки, а вот W2k просто ничего не выдает.
Т.к. твоя программа внешне ничего не делает, ты и не смог увидеть, что она НЕРАБОЧАЯ.
Но есть как минимум два способа проверить:
1) запустить под отладчиком и посмотреть как отвалится загрузчик;
2) посмотреть, какой код возвращает программа, например с помощью такого bat-файла:
@echo %ERRORLEVEL%
По твоему исходнику, она должна возвращать 0, но возвращаемое значение иное ( 128 ).
По твоему исходнику, она должна возвращать 0, но возвращаемое значение иное ( 128 ).
Не знаю, как на такую прогу смотрят старые винды, но NT 5.2 прекрасно переваривает и выдаёт ту цифру, что в исходнике написана. Под WinXP без вопросов работают более "серьёзные" проги, "выровненные" по 4 или 16. Если мне не изменяет склероз, одну такую прогу я успешно запускал под Win95.
Я согласен, что перед использованием подобных опций (особенно /merge) надо "семь раз отмерить", потому что иная прога может и не запуститься.
Неиспользование этих опций может увеличить итоговый размер на пару сотен байт, а использование библиотечных функций может добавить кило 50 веса...
Не знаю, как на такую прогу смотрят старые винды, но NT 5.2 прекрасно переваривает и выдаёт ту цифру, что в исходнике написана. Под WinXP без вопросов работают более "серьёзные" проги, "выровненные" по 4 или 16. Если мне не изменяет склероз, одну такую прогу я успешно запускал под Win95.
Ты полагаешься на свой склероз?
Надо бы опираться на факты, стандарты и документы.
Смотрим смотрим опцию линкера /ALIGN:
The number argument is in bytes and must be a power of two.
Надеюсь, теперь ясно, что /ALIGN:1 ошибочно?
Смотрим стандарт PE-format:
The value should be a power of 2 between 512 and 64K inclusive.
Смотрим описание структуры заголовка PE IMAGE_OPTIONAL_HEADER:
The value should be a power of 2 between 512 and 64K (inclusive).
Теперь делаем выводы:
1. Выравнивание дожно быть кратно 2, поэтому /align:1 не катит, не будет работать.
2. Выравнивание по стандарту должно быть не менее 512, поэтому /align:4, /align:16 работать под W9x не будет, а то, что работает под WinNT - не совсем соответствует стандарту и является исключением, а не правилом, сл-но нет никакой гарантии, что будет работать в последующих версиях, а так же с различными SP.
Я согласен, что перед использованием подобных опций (особенно /merge) надо "семь раз отмерить", потому что иная прога может и не запуститься.
А вот /megre относительно безопасен, главное, чтоб атрибуты доступа к секции соответствовали необходимым.
Неиспользование этих опций может увеличить итоговый размер на пару сотен байт, а использование библиотечных функций может добавить кило 50 веса...
Странно так образно говорить о библиотеках и так конкретно говорить о размере... :D
Ты полагаешься на свой склероз?
Надо бы опираться на факты, стандарты и документы.
Смотрим смотрим опцию линкера
[QUOTE]
The number argument is in bytes and must be a power of two.
Надеюсь, теперь ясно, что /ALIGN:1 ошибочно?[/QUOTE]
Green! исправь меня, если ошибаюсь, но 2 в степени 0 это не 1??:roll:
Green! исправь меня, если ошибаюсь, но 2 в степени 0 это не 1??:roll:
Вот именно.
Трудно доказать факт экспериментом, если он противоречит теории... В прошлом сообщении я приложил программу с выравниванием 16. Проверяйте. На WinNT 5.2 - безотказно.
Минимальная прога с не укладывающимся в понимание Green'а выравниванием 1 под той же ОС возвращает ровно то значение, которое укажешь. В данном случае, 0, но я проверял и другие.
2 Green
У меня в папочке лежат 9 программ. Если бы ты был прав, ни одна не запустилась бы. :)
Green! исправь меня, если ошибаюсь, но 2 в степени 0 это не 1??:roll:
Относительно степени ты прав.
Просто, /align:1 у меня везде не работает, поэтому для себя я трактовал это как 2^n, где n>0.
Вот именно.
Трудно доказать факт экспериментом, если он противоречит теории... В прошлом сообщении я приложил программу с выравниванием 16. Проверяйте. На WinNT 5.2 - безотказно.
Я ж сказал, что проверил. На W98 НЕ РАБОТАЕТ.
Почему не работает тоже объяснил.
Минимальная прога с не укладывающимся в понимание Green'а выравниванием 1 под той же ОС возвращает ровно то значение, которое укажешь. В данном случае, 0, но я проверял и другие.
Специально, для "Кулибиных", которым лень читать стандарты и полагающиеся лишь на "свой склероз", поставил эксперимент: на 4-х ОС из 5-ти не работает. Видимо, нужно показать в картинках, раз документы уже не котируются. Смотри прикрепленный файл с картинками.
2 Green
У меня в папочке лежат 9 программ. Если бы ты был прав, ни одна не запустилась бы.
Так у меня не работают, значит, я прав?
Или это локальная правда, в пределах одного компьютера? :D :D
Я уже столкнулся с твоими неординарным подходом к программированию:
1) "не помешает",
2) стандарты пишутся не для тебя.
А это, видимо, ещё один постулат: "у меня работает, значит все верно".
Непрофессионально, знаете ли...
Ты пользователям своих программных продуктов собираешься (не думаю, что ты уже с ними работаешь) так же объяснять причины неработоспособности твоих творений?
Кстати, ты так и не объяснил свою позицию, кроме как в анекдоте:
"Проверял? Тогда оставь как есть и ничего не трогай!"
Действительно, на все воля Божья, а пути его неисповедимы... :D
Надеюсь, теперь ясно, что /ALIGN:1 ошибочно?
Green! исправь меня, если ошибаюсь, но 2 в степени 0 это не 1??:roll: [/QUOTE]
Я не знаю, в какой литературе хоть раз кто-то встречал, чтобы указывался размер, являющийся степенью двойки и допускалась степень 0? Давай тогда включим и -1, там ведь не написано?
/align:0.5
Даже блоки в памяти в Windows выровняны на слово.
Я не знаю, в какой литературе хоть раз кто-то встречал, чтобы указывался размер, являющийся степенью двойки и допускалась степень 0? Давай тогда включим и -1, там ведь не написано?
/align:0.5
Даже блоки в памяти в Windows выровняны на слово.
-1 включать не можно. процессор не может считать или записывать данные с памяти с середины байта.
и самое главное, я здесь невижу ответа на вопрос ProgMastera. Думаю, ему нужно бы использовать библиотеку ATL и ATL COM AppWizard.
Относительно степени ты прав.
Просто, /align:1 у меня везде не работает, поэтому для себя я трактовал это как 2^n, где n>0.
Мне кажется, что катимся в offtopic, но что поделаешь.
Есть директива #pragma pack(1), и теоретически он работает. Элементи последующих структур не выравниваются.
у Касперского: "Техника оптимизации программ" написано много о выравнивании. Если можно ему верить, то стат. и глоб. переменные выравниваются по усмотрению компилятора в соответствии с их размерами. pack или ALIGN не учитывается.
Автоматические переменные выровнены по адресам кратным 4, из-за того, что машинные команды помещения и снятия данных со стека работают с одним типом данных - 4байтовыми двойными словами.
Динамические переменные, размещаются в куче. malloc напр. выравнивает выделяемые ей регионы по адресам, кратным 16.
и самое главное, я здесь невижу ответа на вопрос ProgMastera.
От части ты прав, надо бы ему ответить. :)
Но с другой стороны вопрос-ответ - это ближе к FAQ, чем к форуму.
Кроме того, ProgMastera некорректно задал вопрос.
Что значит "без использования АПИ"?
Без Win32 API? Без него не выйдет.
Без использования Win32 API напрямую, без врапперов? Тогда мой ответ - WTL/ATL.
Можно самому немного обернуть Win32 API и обойтись без WTL, MFC и т.п.
Я как-то для эксперимента использовал так Shell.Explorer через IWebBrowser2. Прога заняла пару кб. Если надо, могу покапаться в своем хламе.
Мне кажется, что катимся в offtopic, но что поделаешь.
Есть директива #pragma pack(1), и теоретически он работает. Элементи последующих структур не выравниваются.
у Касперского: "Техника оптимизации программ" написано много о выравнивании. Если можно ему верить, то стат. и глоб. переменные выравниваются по усмотрению компилятора в соответствии с их размерами. pack или ALIGN не учитывается.
Автоматические переменные выровнены по адресам кратным 4, из-за того, что машинные команды помещения и снятия данных со стека работают с одним типом данных - 4байтовыми двойными словами.
Динамические переменные, размещаются в куче. malloc напр. выравнивает выделяемые ей регионы по адресам, кратным 16.
Ты путаешь выравнивание секций PE-файла и выравнивание полей структуры и данных.
Это разные вещи!
Если второе обусловлено компиляторами и критериями быстродействия, то первое обуславливается загрузчиком, точнее его реализацией и соответствию формату. При разработке PE-формата (точнее его предшественников) подразумевалось, что начало секции файла должно совпадать с началом сектора дефолтового размера на носителе. Почему, я уже не помню...
Что в описании PE-формата я уже приводил. Результаты работы загрузчиков различных ОС я тоже приводил.
По 0.5, думаю, не стоит выравнивать. :D
ProgMaster не написал, что же именно он хочет запихать в 100 кб. А то, может, там такая мелочь, которая в 100 кб. без напряга сама уместится.
Вопрос о выравнивании данных относится к вопросам по ассемблеру. Ответ сильно зависит от структуры кеша процессора и памяти.
Не вижу смысла дальше обсуждать опцию компоновщика /align.
Green, ты бы сначала понял, что именно я пытаюсь тебе доказать...
Извини, так и не понял... Объясни, что же ты доказывал?
Разве не то, что программа собраная с опцией линкера /align:1 будет рабочей?
Вопрос о выравнивании данных относится к вопросам по ассемблеру. Ответ сильно зависит от структуры кеша процессора и памяти.
Не вижу смысла дальше обсуждать опцию компоновщика /align.
Мы же обсуждали выравнивание секций, а не данных...
Да и /align не имеет никакого отношения к выравниванию данных.
Или я опять в чем-то не разобрался в твоих постах? :D