MASM32 и DELPHI — битва за размер…
Часто говорят о потребностях в оптимизации проекта с целью уменьшения размера программы… Delphi является аутсайдером по этому показателю среди основных языков для разработки системных приложений… Действительно у ламеров есть очень сильный (как им кажется) аргумент — Делфи создаёт пустой проект весом почти 400 кб)).. Напротив асемблер считается передовиком направления создания компактных приложений и по мнению ламеров разница в размерах огромна по сравнению с делфи… Да это так.. но всё же давайте попробуем написать программу хеллоу ворлд… выводящую просто окошко с заголовком Hallo и строкой Hallo World!!! напишим мы эти проги на Delphi и Asm… и посмотрим какая будет разница в размере…
Asm:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
MsgCaption db "Hallo World!!!",0
MsgBoxText db "Hallo",0
.code
start:
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke ExitProcess,NULL
end start
Компиляция:
из MASM32 + укороченный стаб весом 64 байта..
Сохраняем код и кидаем его в файл: asm.asm…
Создаём ВАТ-ник с текстом:
@ml /c /coff /nologo asm.asm
@Link /ALIGN:4 /FORCE:UNRESOLVED /SUBSYSTEM:WINDOWS /MERGE:.data=.text /MERGE:.rdata=.text /stub:stub.bin asm.obj
Имеем ехе-шник весом 624 байта… Нормально… Теперь давай тоже самое на делфи…
DeLpHi:
unit H;
interface
Procedure Start;
implementation
function MessageBoxA(hWnd: cardinal; lpText, lpCaption: PChar; uType: Cardinal): Integer; stdcall; external 'user32.dll' name '_MessageBoxA@16';
Procedure Start;
begin
MessageBoxA(0,'Hallo World!!!','Hallo',0);
end;
end.
Компиляция:
dcc32.exe (от делфи3), Link.ExE, MSPDB50.DLL,(SYSINIT.DCU,SYSTEM.DCU — c урезанным RTL),USER32.LIB + стаб 64 байта….. Сохраняем код в файл: pas.pas… Создаем ВАТ-ник c текстом:
@dcc32.exe -JP pas.pas
@link.exe /ALIGN:4 /FORCE:UNRESOLVED /SUBSYSTEM:WINDOWS /MERGE:.data=.text /MERGE:.rdata=.text /ENTRY:Start$qqrv /STUB:stub.bin user32.lib pas.obj
Кидаем в одну папку получаем размер ехе — 672 байта…
Итог: ни вижу ни малейшего повода поводя считать делфи громозким языком))))
Коментарии на тему что это из журнала хакер не принимаются… В статье МС-РЕМа размер 832 байта… И вообще РЕМ не первый писал об этом ведь не он написал компилятор делфи и линкер))… Да цель статьи получить минимум на делфи… с чем в общем-то и справились…
неплохо, неплохо
когда говорят о разнице в размере между асм и другими прогами написанными на др языках имеют ввиду гораздо объемные листинги, и там очевидно что разница будет составлять разы или порядки.
xxxxxxx, специально для вас, клятвенно обещаем размещать фунции в модулях и dll, чтобы листинги были меньше 🙂
;==== msgbox.asm ====
.386
.model flat,stdcall
option casemap:none
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
extern _imp__MessageBoxA@16:dword
extern _imp__ExitProcess@4:dword
.code
start:
push 0
push offset szAppName
push offset szTextMsg
push 0
call _imp__MessageBoxA@16
push 0
call _imp__ExitProcess@4
szAppName db «Hallo World!!!»,0
szTextMsg db «Hallo»,0
end start
;==== msgbox.bat ====
echo off
if exist msgbox.obj del msgbox.obj
if exist msgbox.exe del msgbox.exe
\masm32\bin\ml.exe /c /coff /nologo msgbox.asm
\masm32\bin\link.exe /ALIGN:4 /STUB:s2b.exe /NOLOGO /SUBSYSTEM:WINDOWS /MERGE:.idata=.text /MERGE:.data=.text /MERGE:.rdata=.text /IGNORE:4078 /IGNORE:4108 msgbox.obj
pause
;stub.exe = 64 байт
На выходе 552 байт, т.е. на Delphi на 22% больше. Не знаю, сможешь ли ты и дальше оптимизировать код на Delphi, а я вот ещё не уверен, что это лучший из возможных результатов на asm. Есть потрясающий пример проги, выключающей компьютер размером всего в 97 байт (fasm). Да, кстати, если убрать ExitProcess (не смертельно), то размер станет.. 480 байт, т.е. есть выигрыш перед Delphi на 40% (проверял — работает). И это, я повторяю, не факт, что предел.
Что про Delphi, то было бы чудесно, если бы все Delphy-программисты писали бы софт так же красиво, как execom, не пришлось бы плеваться при виде простейших утилит размером в 700 K — 1600 K и выше 🙂
Красиво, конечно.
Но дельфи — для визуальной разработки, именно поэтому и сторонников много. Легко, строишь как из кирпичиков… На чистом винапи? Опять визуальность теряется…
А вообще-то, сравнение асма, си, дельфи напомнили мне бесплодность выяснения ответа на детский вопрос: «Кто сильнее — слон или кит»…
mihali4,
> А вообще-то, сравнение асма, си, дельфи напомнили мне бесплодность
> выяснения ответа на детский вопрос: “Кто сильнее — слон или кит”…
respect, все правильно. Сам заголовок меня немного покоробил, поэтому я и написал в эту ветку. А сравнивать их просто глупо, т.к. по размеру asm всегда может дать фору, но не всегда размер программы — это главный критерий. Другой момент — скорость работы программы. Здесь на asm тоже чаще всего можно дать фору. И только по третьему критерию — по скорости разработки — ЯВУ обычно выигрывают у asm.
Помоему все это бред. Сравнивать Можно либо два компилятора(или среду разработки) либо языки, если сравнивать языки то безспорно Delphi намного практичней, если компиляторы (и уровень оптемизации) то Borland Delphi далеко не рулит, его практически по всем параметрам обходит Borland C++ причем контора одна и таже! Я неспорю по поводу того что что то хуже, а что то лучше, я просто пытаюсь сказать, что статья написанна несколько некорректно (в плане выбора Assembler and Delphi), по моему можно было бы лучше сранить Delphi с C++, по всем параметрам провести обзор начиная от среды разработки и заканчивая уровнем оптемизации скомпилированного кода
Дело не в Delphi — компилятор отличный — почище BCB или M$VC++, а VCL. Именно VCL пожирает ресурсы и раздувает объём приложения. Это плата за простоту её использования. Но WinAPI ни к чему. Убогая это штука от M$. Хотя сама Windows (XP) сделана неплохо. Дело в том, что WinAPI делали те, кто делал ещё 16-разрядные Win (1.0…3.11, 95, 98, ME). а линейку NT — другие (например, 2000 — разработка автора Delphi, а XP — её клиентская модернизация). Руководство самого Била (отбор кадров и ценные идеи) предрешило убогость WinAPI. Начиная с 2000 он не лез в дебри разработки системы, но старая идеалогия WinAPI (преемственность, видите ли) осталась и мешает, мешает и мешает.
Альтернатив VCL много, например, KOL&MCK (http://kolmck.net/)
2 а:
Ха! Сам-то подумал сколько глупостей в одном посте написал! Это что-то!
1. MS VC++ v.6 sp.5 — среда и компилятор ИМХО на порядок лучше всего вместе взятого из того, что сделано Borland (может разве кроме Turbo Assembler)
2. «Но WinAPI ни к чему.» и далее по тексту — NO COMMENT
3. Удивительно, что ты отнёс семейство Win 95/98/ME к 16-разрядным системам.
4. Судя по написанному семейства 9X и NT различаются не технологией работы ядра, а именами разработчиков, причем разработчик NT-ядра в количестве 1 человек написал потом дельфи — где ты взял такую траву, что за чушь!
5. К твоему сведению Win32 API — это интерфейс, по которому запускаются на выполнение все без исключений windows-программы, а твоя VCL или какая-то KOL&MCK — это жалкие оболочки над теми же API-функциями, которые в процессе выполнения подтормаживают по сравнению с прямыми вызовами API-функций.
Assembler — это язык процессора, Win32 API — это единственный способ взаимодействия программы с операционной системой, скажем так «язык системы». Asm взаимодействует с Hardware (c процессором, с сопроцессором), а API Calls — с Software (и опосредованно с остальным железом). Это для PE-программ под win.
Я во всем практически полностью согласен с mc-black за исключением одного- Borland C++ всегда делала VC++ и я думаю, что и будет делать, так как и скорость разработки в Borland выше, и оптемизация лучше и т.д.
Антоха,
Ты сравниваешь компиляторы или среды разработки? Если речь о возможности оптимизации, то по какому критерию сравним оптимизацию? По компактности исполняемого PE-файла, по размеру образа программы в памяти, по скорости исполнения кода, по выполнению какого-то конкретного алгоритма/цикла, по удобству отладки, по чему-то ещё? А на мой взгляд MS VC предпочтительнее хотя бы тем, что все примеры из MSDN будут без доработок работать на MS VC, а эта первичная тех. документация многого стоит. Сам я ни на том, ни на другом если что не пишу, т.е. являюсь лицом не заинтересованным. Если есть пример сравнения одного и того же кода, написанного для двух этих сред и двух компиляторов соответственно, то пожалуйста код с студию!? 🙂
P.S. Я не против borland’цев вообще и delph’истов в частности, я противник категорических заявлений типа то-то и то-то — это предел совершенства. Куда важнее прямо растущие руки у программиста 🙂
привет, mc-black.
не стану отвечать в твоем твоем любимом стиле, но совершенно очевидно, что твоя трава вовсе не слабее!
ребята не давайте повода надутым перцам вводить вас в заблуждение. люди которые пишут про то что «Asm взаимодействует с Hardware», таким образом противопоставляя asm всему остальному, пусть сравнят для меня пароход и космический корабль, микросхему и каменный кремниевый топор, далее может сами можете продолжить.
по моему первый вопрос, который должен задать себе каждый, прочитавший данный subj «могу ли я считать себя настоящим программистом, если до сих пор читаю такое». а еще скажите сколько времени потребуется для написания ала-блокнота на асме и в любой из IDE, а чата, приложений для работы с базами данных. короче не в ту сторону думаете.
думаю на этом обсуждение можно закончить
mc-black,
🙂 . Я сравниваю по удобству (среда разработки), по моему с билдером проще, и быстрее нежели с mfc в visual. плюс ко всему если скомпилировать проект на том и на другом, а затем дизасемблировать, то код в проекте написанном на builder С++ отлаживается по моему проще, а ведь в builder есть еще и различная оптемизация! И нехилые возможности по настройки компилятора.
pupkin,
Блокнот можно и на asm написать, только теби оно надо? ASM для батек, кто знает его тот может написать не просто блокнот а все, что угодно с ахриненной оптимезацией на скорость. 🙂
pupkin а ты сам-то хоть писал на АСМ. На написание аля-блокнота уходит столько же времени, что и на других языках, а вот работа с убогими объектами WIN-API — другой разговор, тут с Delphi , C++, VC не поспоришь, тебе, как говорится, на халяву предлагают отличные объекты, с нужными свойствами и параметрами, используя их, твоя прога проигрывает в скорости и размере, но, извини, никак не во времени написания. Выбирай, что тебе надо, головомойка со стандартными объектами + скорость + маленький размер (АСМ), или быстрота написания — головная боль = маленький размер — скорость. Уверяю, лучше выбрать второе, к тому же обычному юзверю до лампочки как ты написал прогу, главное чтобы она работала.
На самом деле дело в результате. И только в нем.
На чем писать человек решает исходя из своих привязанностей и способностей.
Заказчик в большинстве случаев смотрит на результат, а не на методы достижения.
Всяк кулик свое болото хвалит.
А что-то голословновно доказывать — это извините меня «треп».
Спор ни о чем.
Ассемблер нужен не для разработки програм с нуля, он нужен для написания сверхбыстрых и компактных алгоритмов для сложных задач. Например тяжёлые сервера в организациях требуют огромной оптимизации а также огромной скорости работы.
Впрочем достаточно даже писать на C, разница в скорости будет не критична, зато в результате меньше путаницы будет и код наглядней для изучения другими людьми.
А winapi неплохая штука, работает с неплохой скоростью. Но, имхо, апи очень «узкая», не протолкнуться, много усилий нужно чтобы сделать что-то эффективное и удобное.
Статья на 4-ку.
Позабавило, особенно коментарии 🙂 Рискну вставить и свои две копейки.
>а еще скажите сколько времени потребуется для написания ала-
>блокнота на асме и в любой из IDE, а чата, приложений для работы с
>базами данных.
Немного. Блокнот пишется в любом редакторе ресурсов, а-ля VCL 😉 Чатов не писал, но вот простой обменник на сокетах занял часок, но тогда я сокеты знал плохо, приходилось в документацию постоянно лазить. На работу с базой данных, через ODBC, я потратил пару часов, обеспечив как хранение/обновление данных, так и их выборку. Причем основное время ушло на составление SQL-запросов 😉 И все дальнейшее расширение сведется так же к SQL, поскольку «обертка» вокруг ODBC получилась довольно универсальной, хотя и замысловатой, это же асм 😀
Вообще сравнивать размер подобным образом некорректно. Здесь сравнивается не компактность получаемых программ, а размер хидеров экзешников 🙂
2 Demonid7:
Respect!!! =)
От себя к сказанному тобой добавлю:
1. Блокнот написанный мной с подсветкой синтаксиса асм, с мультиязычным интерфейсом я писал — это была моя первая программа на асм, я тогда только учился. Вот ссылка:
http://mc-black.narod.ru/x3mEd.htm
2. Чат.. А нах он? )) Не писал и никогда такой глупостью не займусь. Довольно мне того, что друг дал исходник icq-бота на асм. Надо будет — разберусь.
3. Приложение по работе с базами данных: за один вечер написал обертку к odbc с привязкой к listview, выводит любой SQL-запрос в виде таблицы. С этой маленькой наработкой можно скармливать программе любые SQL-запросы и программирование уже будет мало отличаться от ЯВУ.
Еще подкину дров в костер:
> Компиляция:
> dcc32.exe (от делфи3), Link.ExE, MSPDB50.DLL,(SYSINIT.DCU,SYSTEM.DCU
> — с урезанным RTL),USER32.LIB + стаб 64 байта…
Сколько будут при этом стоить средства разработки? Пакет Masm32 как и входящий в него MASM v6 32-bit обходится бесплатно. Это при лицензионной чистоте. Не нравится masm — всё это можно повторить на ЛЮБОМ бесплатном ассемблере (fasm/nasm/wasm/lasm и др.). Wind’a строго говоря в обоих случаях может быть не установлена, возможно попрет и под Wine. Во сколько обойдется разрботка в коммерческой среде от Borland? У кого задача будет решена дешевле?
Компилятор у Delphi быстрый и создает компактный код.
Но основные библиотеки RTL и особено VCL оставляют желать лучшего 😕
Format PE native 4.0 on ‘null’ as ‘exe’
include ‘win32ax.inc’
section ‘.all’ data code readable writable executable
invoke MessageBoxA,0,’Hallo World!!!’,0,0
ret
data import
library user32, ‘USER32’
import user32, MessageBoxA, ‘MessageBoxA’
end data
FASM, 480 байт штатными средствами. null — пустой файл. Собран как драйвер, после компиляции изменить поле subsystem опционального заголовка на 02h (windows GUI)
У меня проблема!
Объявляю:
function GetDC(hWnd: Integer): integer; stdcall; external user32 name ‘GetDC@4’;
Выводит:
demo.obj : warning LNK4033: converting object format from OMF to COFF
demo.obj : error LNK2001: unresolved external symbol @@HandleFinally$qqrv
demo.obj : error LNK2001: unresolved external symbol GetDC@4
В чем проблема?