Print This Post MASM32: Начало

Суббота, 21. Август 2010
Раздел: Assembler, Windows, Для новичков, автор:

Решил начать цикл статей по ассемблеру, и, в частности, по MASM32. Пригодятся эти мануалы с примерами тем, кто хочет поднять свои навыки программирования и развить умение программировать на ассемблере. Пакет MASM32 - это не просто голый ассемблер. В нём есть огромное множество облегчающих разработку софта вещей - пользовательские макросы, встроенные функции и макросы, дебаггер и прочее, и обо всём этом я буду рассказывать. Конечно, читать такие статьи будет гораздо легче тем, кто уже умеет программировать на каком-нибудь языке. Если вы программируете на каком-нибудь говне вроде Visual Basic, или фанатеете от перетаскивания компонентов и кнопочек на формы в дельфи или Borland C++ - не расстраивайтесь, я расскажу, как можно перетаскивать кнопочки и в ассемблере. Разумеется, никаких стандартных облегчающих жизнь компонентов здесь не будет, но это побудит разобраться с WinAPI - огромной кладезью полезных функций, которые способны делать всё, начиная от чтения данных из сокета и заканчивая отображением окон.

Собственно, эту статью я начну с примера простого GUI-приложения на MASM. Конечно, проектировать дизайн окна мы будем визуально (я же обещал). Для этого сначала следует скачать визуальный редактор ресурсов ResEd. Запускаем его и видим интерфейс:

Создаем новый файл ресурсов (File - New Project и вводим имя). В правой верхней панели появляется значок папки и имя файла. Кликаем по ней правой кнопкой и нажимаем "Add Dialog". Теперь мы можем визуально спроектировать интерфейс окна и изменить его настройки. Я создал простое окно TEST_DIALOG с двумя кнопками TEST_BTN и EXIT_BTN:

Если вы успели обрадоваться - не спешите: здесь нельзя программировать, можно только делать дизайн интерфейса. Теперь необходимо добавить в наш файл ресурсов еще пару вещей. Первое - это include-файл с определениями всех констант, который будет необходим компилятору ресурсов MASM32. Как и раньше, нажимаем правой кнопкой мыши по значку папки, выбираем "Include file", "Add" и вводим путь. У меня это C:\masm32\include\RESOURCE.H. У вас может быть и другой, зависит от папки установки masm32 (как? вы еще не установили его?).

Теперь еще одна вещь. Пусть наше окно и кнопки выглядят в современном XP-стиле. Для этого необходимо добавить к файлу ресурсов XP Manifest. Добавляется он аналогично предыдущим пунктам (Add XP Manifest).

Теперь сохраняем файл ресурсов. Он должен выглядеть примерно таким образом:

Осталось написать программу. Я в качестве редактора предпочитаю обычный Блокнот Windows. Сначала я приведу полный листинг, а потом прокомментирую его построчно:

Итак, начнем:

Эти директивы говорят о том, что мы пишем код под 386 архитектуру процессора (это так и будет всегда), вторая говорит о том, что модель памяти мы используем плоскую и вызовы функций по стандарту stdcall. Этот стандарт подразумевает, что аргументы функциям передаются через стек в обратном порядке, и функция сама должна удалять их оттуда. Кроме того, функции сохраняют регистры ebx, edi и esi и возвращают значение в регистре eax. Если вы сейчас ничерта не поняли - не расстраивайтесь, это всё прекрасно разъяснено в гугле - и про регистры, и про стек. Если вы занимаетесь программированием, то понять это не составит труда.

Здесь мы подключаем необходимые библиотеки. kernel32 содержит функцию ExitProcess, user32 - всякие GUI-функции, comctl32 - функции работы с common controls, masm32 - библиотека встроенных функций masm32, я не знаю, зачем я ее здесь подключил, потому что она все равно в этом простом проекте не используется. Ну, лишнего объема, как в дельфи, это не добавит, если функции из библиотеки не используются. Я расскажу о ней в будущем. uselib - это макрос masm32, который всё необходимое позволяет одной строкой подключить. Только представьте, эти три строки эквивалентны следующему коду:

Как узнать, из какой библиотеки функция? Смотреть msdn.

Идем дальше...

Эта строка представляет собой прототип процедуры. Если вы программируете на C или C++, то знаете, что это такое, если нет - я поясню. Функцию нельзя вызывать до того, как она будет объявлена, поэтому в начало файла часто пишутся прототипы функций, расположенных в других файлах или ниже места первого вызова функции.

Этими строками мы просто объявили некоторые значения из нашего файла ресурсов new.rc. Можно было бы этого и не делать, но с ними программа будет более читаемой.

В этом куске кода у нас объявляются глобальные переменные в секции неинициализированных данных. Что это такое? Это просто переменные, не имеющие начального значения. Они не занимают места в получающемся после компиляции exe-файле. В hInstance мы будем хранить указатель на модуль нашей программы (зачем - позже поясню), а в icce - структуру INITCOMMONCONTROLSEX (также объясню позже). dd - он же DWORD - тип данных "двойное слово". В C++ такой тип имеют int, long и все указатели, но C и C++ являются более типизированными языками, а в ассемблере всё сводится к двойным словам (4 байта).

Чтобы объявить секцию инициализированных данных и глобальные переменные в ней, пишут так:

В нашей программе тоже будет секция инициализированных данных, просто она неявно объявляется, далее я расскажу об этом.

Что же происходит здесь? Здесь мы уже объявляем секцию исполняемого кода и метку start, которую потом объявим точкой входа.
Мы инициализируем объявленную ранее структуру icce и вызываем функцию InitCommonControlsEx. Инструкция mov загружает данные в регистр или ячейку памяти. Представьте, что мы пишем

... и всё станет понятнее. Встроенный макрос invoke используется для вызовы любых функций, у которых есть прототип (а прототипы всех WinAPI прописаны в заголовочных файлах MASM32, которые мы подключили в самом начале программы). Sizeof возвращает размер структуры в байтах, offset позволяет получить смещение в памяти какого-либо байта. Есть еще addr, позволяющая получить смещение какого-то байта, размещенного в памяти по заранее неизвестному адресу (например, для локальных переменных в процедурах).

Теперь дальше - мы получаем указатель на начало нашего исполняемого модуля. Опять-таки, представьте, что мы пишем

Все stdcall-функции возвращают значение в регистре eax, как я уже говорил, а GetModuleHandle как раз stdcall WinAPI. Ах да, у вас, вероятно, есть вопросы по этим функциям, если вы впервые слышите про WinAPI? Ну так вбейте название непонятной функции в гугл, и получите ссылку на msdn с подробнейшим описанием.

И, как вы уже могли догадаться, мы создаем диалоговое окно функцией DialogBoxParam с указанием идентификатора диалога из файла ресурса (TEST_DIALOG = 1000). Эта функция начинает цикл сообщений windows с использованием функции WndProc, на которую мы передали указатель. Это типизированная функция, далее я опишу ее, но пока что - пара слов о цикле сообщений. Каждое окно в Windows получает множество сообщений от системы или других приложений, от других окон или от своего же в непрерывном цикле. Процедура WndProc будет эти сообщения получать, а мы будем в ней обрабатывать часть сообщений. которые нужны нам.

Далее я распишу код с комментариями:

Ну и последнее:

Здесь мы устанавливаем точку входа на метку start, т.е. с нее начнется выполнение программы.

Ну что же, сохраним код как new.asm, закинем в одну папку new.rc, new.asm и xpmanifest.xml и скомпилируем всё следующим bat-файлом:

После компиляции и линкования получаем программу размером 2.5 кб, которая еще и работает. Ну не прелесть ли?

Надеюсь, эта статья была вам полезна. Хотя о чем это я... Если вы дочитали до этого момента, то явно почерпнули для себя что-то полезное. Надеюсь, вам уже хочется писать свои GUI-программы на ассемблере с использованием MASM32, наполняя их функционалом, ну или хотя бы немного заинтересовала эта тема. В следующей статье я напишу что-нибудь более полезное, чем простой "Hello, world!", и представлю Вашему вниманию.

И последнее. Если после прочтения вы будете находиться в состоянии, подобном этому - не расстраивайтесь, у вас ещё все впереди! :)

 Обсудить на форуме


Получать обновления на почту:     

Комментариев: 117 к “MASM32: Начало”


  1. Игорь :

    Разобрадся и в стеке и в организации памяти а dx ни захотел почом с bat-файлом или на ошибку указать. Компиляция завершаетсф неудачей

    [Ответить]


  2. Игорь :

    Какой путь прописываем сюда в переменную патч - SET PATH=C:\Masm32\bin -?

    [Ответить]


  3. Игорь :

    Какой путь мы должны прописать в переменную patch- SET PATH=C:\Masm32\bin-?И я так и делаю вообщето

    [Ответить]

    dx:

    Очевидно, тот путь, где у тебя масм 32 установлен. Знаешь, иди разбирайся сам, я тебе больше ничего подсказывать не буду, ты все равно ничего не поймешь. Статья и так как для дебилов разжевана была, а ты умудряешься третью неделю компилировать по всему готовому.

    [Ответить]

    Игорь:

    Да я все понял я так и делал все. как ты написал от а до я!!Ну попробую еще!!!

    [Ответить]

    Игорь:

    А что мы задаем после знака роцента в батнике %1 - ?

    [Ответить]

    dx:

    Ты совсем отупел и не можешь инструкцию прочитать? Батник не надо редактировать, берешь и сохраняешь КАК В СТАТЬЕ ДАН.
    А потом читаешь мой комментарий чуть повыше и делаешь по пунктам, не задумываясь.

    Игорь:

    Просто покажи как выглядет батник с уже заданными параметрами а то при запуски из нужной директории выдается ошибка - не удалось открыть new.asm и new.rc,а xpmanifast я экспортирую из самого Resed,-а.Я все так и делал. как ты щас распиал от а до я и именно в этой последовательности три недели.

    Приведи батник со значениями, которые стаят после параметра %1.asm %1.rc

    Я задаю параметр %1new.asm и %1new.rc, что указываешь ты-?

    dx:

    А вот не подскажу, ты мне надоел, даже текст для полных идиотов выполнить не можешь

    Kaimi:

    Ну раз просишь показать, то вот: http://vimeo.com/41038645


  4. Игорь :

    Все так и делаю три недели. так же точ в точ, как у вас ос стоит и разрядность-?Какую версию xp у меня просто windows7 32-ая на xp перейти не могу, система битая(пиратская) слететь может,может из за этого-?Но ведь и в 7-ке есть старые библиотеки xp

    [Ответить]

    dx:

    Я на семерке x64 все собирал и собираю. Просто у кого-то руки совершенно криво растут из жопы.

    [Ответить]

    Игорь:

    ЗАРАБОТАЛ!!!!СПАСИБО!!!!Я ТАК ВСЕ И ДЕЛАЛ, ПРОСТО СТАБ64 НУЖНО БЫЛО УСТАНОВИТЬ!!ПАШЕТ!А ПРЕПОД НЕ СМОГ ХА!

    [Ответить]

    dx:

    И ты бы не смог, если бы тебе полностью разжеванное видео не показали. По такому видео и обезьяна бы сделала.

    Игорь:

    Аха я проанализировал уйму ошибок и знаешь я изначально все делал верно, просто stub64 exe был не рабочий,пото посмотрел цикл вшаих статей и понял. что он у вас слетает, а так я во всем разобрался и в механизмах работы ядра и в процессе компиляции. и понял что ошибка вызвана строкой в котороей передоваемый параметрк указывает, компилятору какие файлы мы компилируем,компилятор был не рабочий в рпезультате возникала ошибка и фалй ну далось открыть,так как не удавалось запустить пакет компиляции!!Что уделал я тебя, я нашел ошибку. которую ты проморгал и ты щас взбесился!!ИЗНАЧАЛЬНО ВСЕ ДЕЛАЛ ВЕРНО НО НЕ РАБОТАЛ STUB64 EXE!А хамить ты мастак!Но все равно спасибо за то. что поделился идеей

    dx:

    Каково это - сдавать диплом в 14 лет?


  5. Игорь :

    СПАСИБО ВАМ ЕСЛИ ЧЕ НЕ ДУЙТЕСЬ!!!

    [Ответить]


  6. Игорь :

    ТОЧНЕЕ ПЕРЕУСТАНОВИТЬ СТАБ64!!!ЧТО Я И ЗДЕЛАЛ СКАЧАЛ ПОВТОРНО УДАЛИЛИ СТАРЫЙ И УСТАНОВИЛ НОВЫЙ !!!

    [Ответить]


  7. Игорь :

    И КАКОРЕ ВИДЕО?!!ГДЕ-?!Я ЕЩЕ 2 НЕДЕЛИ НАЗАД РАЗОБРЛАСЯ,КАК ОТКОМПИЛИРОВАТЬ ИСХОДНИК И ВАМ СЮДА СКИДЫВАЛ А ВЫ ВСЕ ВАЛИЛИ НА МЕНЯ А ФАТАЛЬНАЯ ОШИКБА В СТРОКЕ КОДА, ГДЕ ПАЕКТУ КОМПИЛЯЦИИ ПЕРЕДАЕТСЯ ЗАДАННЫЙ ПАРАМЕТР УКАЗЫВАЮЩИЙ КАКИ ФАЛЫЙ НУЖНО ОТКОПИЛИРОВАТЬ В EXE,УКАЗЫВАЛА ПРЯМО НА ТО, ЧТО НЕ УДАЛОСЬ ЗАПУСТИТЬ STUB64 EXE И НЕ ВЫ С ВАШИМ ОПЫТОМ, НИ НА ФОРУМЕ ПРОГРАММИСТОВ НИ ПРЕПОДОВАТЕЛЬ В ЭТОМ НЕ РАЗОБРАЛИСЬ А СТУДЕНТ , КОТОРЫЙ НАЧАЛ ВСЕ С 0 РАЗОБРАЛСЯ АБСОЛЮТНО ВО ВСЕ, ОКАЗАВШИСЬ НА ПОТОЛОК ВАС ВЫШЕ!

    [Ответить]

    Kaimi:

    КОНЕЧНО ВОТ ЭТО ВИДЕО!!??111---+++=== Студент? Вы себе льстите, как максимум - школьник, который не в состоянии написать пару-тройку предложений, не совершая десяток ошибок в каждом. Также стоит отметить феерическое содержание вопросов, которые Вы изволили задавать на форуме программистов, да и заявление "разобрался и в механизмах работы ядра и в процессе компиляции" вызывает истерический смех, не более.
    Если Вы такой эксперт и во всем так круто разбираетесь, то зачем было задавать все эти идиотские вопросы, которые вообще не должны возникать у адекватного человека?

    [Ответить]

    Игорь:

    Опечатки это нервы,а начинал я все с 0 -я поэтому и задавал вопросы,но во всем разобрался за неделю. Я же вам скидывал результаты компиляции, с просьбой пояснить, где здесь ошибка.Я все это время читал статьи и общался на форуме и я не бухаю и ни лапаю девок а потом ни играю часами в контрстрайк,ни лапаю потому что занят.Это вообще ответное заявление

    [Ответить]

    dx:

    Диплом с нуля, с нулевыми знаниями по теме? Это прекрасно!
    Интересно, чем же ты занят был несколько недель? Не мог почитать хэлпы к программам ml, link и компилятору ресурсов? И собрать все без батника? Надо было на протяжении 6 страниц трахать мозг людям на форуме, даже не пытаясь понять, что они советуют, ну и нам заодно.


  8. Игорь :

    Ворос а если мне нужно откомпилировать только текст программы, батник выглядет так LINK /nologo 1%.obj/SUBSYSTEM:WINDOWS /STUB:64stub.exe /FILEALIGN:512 /VERSION:4.0 /MERGE:.rdata=.text /MERGE:.data=.text /SECTION:.text,EWR /ignore:4078 /RELEASE /BASE:0x400000
    так как я компилирую только исходник, параметр RES отбрасыаю, так как rc-файл не использую-?

    [Ответить]

    dx:

    Да, если компилируешь без ресурсов, то ты их и не указываешь

    [Ответить]


  9. Игорь :

    dx, просто один исходник редкий попался, большая часть написанна на ассемблере,часть на делпни,как его откомпилировать можно http://programmersforum.ru/showthread.php?p=1085889#post1085889

    [Ответить]

    dx:

    Без понятия, не знаю, как асм вкомпиливается в дельфи, да и дельфи не знаю.

    [Ответить]

    Игорь:

    dx помоги разобраться с шибкой A2154 - syntax error in control-flow directive, чем она может быть вызвана-?

    [Ответить]

    Игорь:

    dx,на Wasm.ru огневая поддержка нужна

    [Ответить]


  10. Евгений :

    Здравствуйте, подскажите пожалуйста в чем может быть проблема: сделал все согласно вашей статье, но батник создает лишь файл *.res и не создает *.obj. Я понимаю, что ошибка в *.asm, но где, если я все скопировал с Вас?
    винда - Windows 7 64
    масм32 в корне на диске C
    файлы проекта на C:\masm32\projects\p1\

    [Ответить]

    dx:

    А какие ошибки в консоль выводятся? Вообще, что выводится в консоль?

    [Ответить]

    Игорь:

    Зачем создавать отдельную папку-?Все кидаешь в include, проект называешь(исходник проекта) 1new и компилируешь батником. В ту же директорию кидаешь stub64.exe батник и rc-файл,батник сохраняешь, как make.bat.

    [Ответить]


  11. integra :

    kaimi отдельное спасибо за видео!

    [Ответить]


  12. Андрей :

    Автору спасибо, все ясно и понятно, побольше бы подобных статей, ссылка с ютуба улыбнула, иногда и правда впадаешь в такое состояние.

    [Ответить]


  13. Катя :

    Подскажите пожалуйста как организовать умножение для целых чисел произвольной длины.

    [Ответить]

    dx:

    Скачайте исходники библиотеки, например, MPIR и посмотрите. Там есть как версия на ассемблере (fasm, кажется), так и на Си.
    Ну или погуглите, решений масса.

    [Ответить]

    Катя:

    Спасибо. Посмотрю. Только вот в гугл я не нашла для себя нужного, правда я искала конкретно на MASM, что мне собственно и надо. А переделывать код с одного языка на MASM я не способна из за плохого знания ассемблера.

    [Ответить]

    dx:

    Если нужно готовое решение, причем язык незнаком, то проще выдернуть из какой-то библиотеки либо заказать у фрилансеров или у кого еще.

    qq:

    Всем, привет, еще один нубский вопрос, получила ошибку А1000 невозможно открыть файл /масм32/инклуд/Windouws.inc

    Kaimi:

    Сомневаюсь, что существует файл Windouws.inc. Все возможные причины описаны в мсдн http://msdn.microsoft.com/en-us/library/xkb5t8f2%28v=vs.80%29.aspx


  14. Иван :

    Требую продолжение банкета

    [Ответить]


  15. Пауль :

    пытаюсь разобраться как работает Ваш "Пакет для компиляции MASM32" выполнил все согласно инструкции скопировал архив распаковал и в папку скопировал файл 1.asm файл имеет такой текст:
    .386
    .model flat,STDCALL
    include win32.inc
    extrn MessageBoxA:PROC
    extrn ExitProcess:PROC
    MessageBox equ
    .data
    szMsg db 'Это МОЯ ПРОГРАММА',0
    szCapt db 'УРА!!',0
    .code
    start:
    call MessageBox,0,offset szMsg,offset szCapt,0
    call ExitProcess,0
    ends
    end start
    далее опять согласно указаний "Запускаем cmd.bat. В открывшейся командной строке пишем:

    make_exe имя_asm_файла - для компиляции простого exe-файла (имеется только файл *.asm);"

    в моем случае это выглядит так:make_exe 1
    получаем такой результат:
    если в win7 64
    "ML" не является внутренней или внешней
    командой, исполняемой программой или пакетным файлом.

    E:\OS\SOFT\compiler_minimal>

    если в виртуалке то
    Assembling: 1.asm
    1.asm(3) : fatal error A1000: cannot open file : win32.inc

    C:\compiler_minimal>

    [Ответить]

    dx:

    А откуда должен был взяться файл win32.inc, который в тексте программы фигурирует? В пакете для компиляции такого файла нет, вот ассемблер и ругается.

    [Ответить]

    Пауль:

    Согласен, скопировал такой файл в папку inklude ошибка таже, скопировал в папку compiler_minimal реакция такая:

    Assembling: 1.asm
    1.asm(12) : error A2008: syntax error : ,
    1.asm(13) : error A2008: syntax error : ,
    1.asm(14) : error A2008: syntax error : ends

    E:\OS\SOFT\compiler_minimal>

    вообще этот текст был написан для TASM и он там работал но это был тестовый пример. На кибер форуме посоветовали компилировать в MASM но что-то тоже не очень получается. Думаю мои вопросы могут вызвать ваш гнев как и вопросы пользователя Игорь, но не всем же было откровение и кто-то начал изучать ассемблер с ваших статей так что вы уж не обессудте. Итак что делаю не так моет нужно по другому переписать файл make_exe.bat?

    [Ответить]

    dx:

    Синтаксис TASM несовместим с синтаксисом MASM, думаю. Поэтому и не компилируется.


Оставьте ваш комментарий