Masm32 для чайников
Деление для чайников
Подскажите как правильно провести деление и потом вывести на экран (выражение y=(213 + x — c )/4).
Ошибки MASM32 — cannot open file : .\masm32\include\windows.inc
установил MASM32, прописал в патче путь, выдаёт ошибки при компиляции такого рода : Microsoft.
Ассемблер под Windows для чайников
Приветствую, помогите разобраться с 6-м уроком. Ни как не могу понять эту часть кода .
(MASM32 Editor) для новичков
Знающие люди помогите изучить асемблер много литературы но не могу понять его. Знаю только дельфи.
Компиляция программ для DOS в MASM32
проблема в том, что через командную строку код компилится но линкером link16, я пишу в radasm и.
Ассемблер для процессоров Intel Pentium
Зубков — Assembler для DOS, Windows и UNIX
Александр Крупник — Ассемблер. Самоучитель
Пирогов В. Ю. Assembler для Windows
Assembler & Win32. Курс молодого бойца
Изучаем ASM за 7 дней
Юров В. Ассемблер практикум.
Начни правильно, бери FASM. Синтаксис более лаконичный чем у остальных в частности и у masm32.
30.07.2014, 09:43 | |||
30.07.2014, 09:43 | |||
Настройка MASM32 для Visual studio 12 Компиляция программ exe для DOS в MASM32 Assembler & win32 курс молодого бойцаКак я и обещал, мы с вами займемся программированием под win32. Выполняю свое обещание. Хотя, честно говоря, нижеследующий кусок текста мне уже совсем не нравится. То есть сначала он мне понравился, но потом некоторые товарищи, чье мнение я весьма уважаю и ценю, его раскритиковали в пух и перья. #1. Однажды студент по имени Дениска Ричи сел изучать абсолютно новый для него язык программирования. Первое, что он сделал — написал программу «Hello, World», и, что самое удивительное, она у него заработала. Когда же он перелистнул следующую страницу своей умной книжки, то ни черта не понял. То есть задним умом своей головы он, конечно же, понимал, что большинство известных ему программ умеют намного больше, чем тупо приветствовать мир, однако понять, каким это извращенным образом такие здоровские штуки можно запрограммировать, он не мог. #2. Между тем, вопрос о минимальном приложении — это вам не «кто идет за «Клинским» (конечно же, тот, кого в прошлый раз от «Балтики-медового» мутило), и даже не тот, «кто потом пойдет сдавать бутылки» (конечно же тот, кого систематически дерут в раздевалке!). Минимальное приложение — это есмъ альфа и омега программирования, сцилла и харибда отладки, инь и янь сопровождения и даже (давайте не будем бояться этой правды жизни!) эпос и анус раскрутки программного продукта! И именно поэтому за много-много лет никто так и не усомнился в правоте Кнута, который утверждал, что если: то бессильна даже банка со сметаной, и все, что в этом случае остается — брать в руки биту и идти в лес, выгонять из дубовых дупел пчел. Как свидетельствует вышеозначенная формула, вопрос о минимальном приложении (речь идет именно о приложениях, то бишь applications, а вовсе не о каких-нибудь там VxD) — совсем не простейший, и представляет отнюдь не академический интерес. Даже прибалдевшему от морковки кролику должно быть очевидно, что любое приложение обязано выполнить как минимум две не такие уж и простые задачи: а) стартовать, получив при этом нормальный доступ к ресурсам рабочей среды, В языках высокого уровня подобные процессы обставлены всяческим сервисом — тут тебе и табун девок, накачанных силиконом, и водитель, готовый хоть на руках тащить автомобиль на стоянку, и услужливый швейцар, который при необходимости занесет на повороте хвост, если таковой, конечно же, имеется, и крашеный негр Ванька-каин, который в любое время суток до блеска готов отполировать ботинки.
Практически это означает то, что вы берете в руки крутейший инструмент, который не имеет абсолютно никакой защиты от дурака. И если какой-нибудь дельфийский компилятор будет некоторое время удивляться вашим попыткам выстрелить себе в ногу, (а потом возьмет и выстрелит в ногу сам!) то ассемблерный не скажет ни слова, полагая, что имеет дело с профессиональным террористом, который знает что делает. А раз любвеобильной мамочки рядом с нами не будет, то прежде чем взять в руки это мощнейшее «оружие», надо сначала сходить в аптеку и закупиться не только зеленкой и йодом, но и всевозможными средствами контрацепции. И только тогда, в полном вооружении, брать в руки черный с черепушкой флаг, вешать на шею барабан и отправляться в густой таежный лес, учиться делать рокетджамп и брать медведя голыми руками. #3. Итак, с криком «банзай» (восточная школа) либо «мастдай» (западная школа), открываем текстовый редактор и набираем там исходный текст (в обиходе называется сырец) минимального приложения на языке ассемблера. Вот она, эта песнь души измученного кролика, из которой, как говорится, ни строчки вырезать, ни матерного слова добавить. Однако, это всего лишь своего рода нотный стан с нарисованным на нем скрипичным ключом, размером и нотами. А разве многие из нас могут наслаждаться музыкой, нарисованной на бумаге? Вот именно! Поэтому давайте сначала загрузим эту партитурку в мясорубку, покрутим ручку и посмотрим, какая бяка появится у нас на выходе. Мясорубкой мы будем пользоваться специальной, виндозовской. Называется она MASM32, версию имеет 7.0, весит 5 Мб, а скачать ее можно здесь. #4. Фирма Microsoft никогда не документировала, каким это извращенным способом можно писать приложения под Win32 на Ассемблере. Конечно же, в ее Driver Development Kit (DDK) есть парочка соответствующих топиков, но они относятся исключительно к разработке виртуальных драйверов VxD и прочих специфических штук. Ни для кого не секрет, что для программирования в среде Windows необходимо иметь многочисленные ссылки на данные, такие как прототипы функций, структуры, типы и определения констант, макросы. и так далее. Так вот, все вышеперечисленное богатство как раз и поставляется с DDK. Однако, вот беда, «заточено»-то оно под Си :(. #5. Делать EXE’шник, как всегда, мы будем в два этапа. Для начала возьмем исходник minimal.asm и «заведем» нашу мясорубку следующей командной строкой (каталог с исходником должен быть текущим): Ключ /c говорит о том, что мы хотим только оттранслировать исходный файл, но не компоновать. Ключ /SUBSYSTEM с параметром WINDOWS говорит линкеру о том, что мы собираемся собрать экзешник для подсистемы Windows. Другие возможные значения: CONSOLE — если мы собираемся делать программу с текстовым интерфейсом а-ля ДОС, NATIVE — если драйвер устройства, и POSIX — если мы собираемся писать программы, ориентированные на стандарты POSIX и более или менее переносимые под разные Юниксы (для которых эти стандарты и писались). #6. .386 — это директива ассемблера, определяющая набор инструкций процессора, которые могут быть использованы в программе (позже мы проведем четкую границу между инструкциями, директивами и командами). По умолчанию транслятор полагает, что программа пишется для процессора 8086 и сопроцессора 8087. Но, посудите сами, какая под него может быть Винда? Для приложений win32 необходимо указывать либо .386, либо выше (486, 586, 686) — в зависимости от того, собираетесь ли вы использовать возможности, предоставляемые процессорами/сопроцессорами последующих поколений или нет. Впоследствии мы будем также использовать p-версию этой директивы (486p, 586p), что даст нам доступ к страшным и ужасным привилегированным командам, которые нехороший «дядька» Микрософт подмял под себя, и выпросить их у «мелкомягких» будет не так уж и просто. #7. .model flat, stdcall. Первый параметр — это модель памяти. Например, COM’овские программки, которые мы с вами раньше писали, соответствовали модели tiny, то есть «крошечной» — они запросто помещались в 64 Кб памяти, и никаких проблем с адресацией данных у нас не было. Однако если бы мы захотели написать под ДОС программу во много раз большую, чем 64 Кб, т.е. превышающую размер сегмента, нам пришлось бы познакомиться с таким динозавром, как оффсетно-сегментная адресация, и использовать, в зависимости от навороченности программы, модели small, medium, compact или large. Под Windows же у нас есть одна-единственная «правильная» модель памяти — flat, то бишь «плоская», позволяющая нашей программе благодаря страничной адресации легко и просто работать с 4 Гб виртуальной несегментированной памяти. И это есть хорошо! Ибо теперь, как сказал некто Вал.Ик., нам не нужно смотреть на мир сквозь замочную скважину 64 Кб-сегмента. (C) #8. .includelib kernel32.lib — эта директива передается компоновщику и сообщает, что наша программа должна быть слинкована с указанной библиотекой, в данном случае с kernel32.lib. Библиотека представляет собой энное количество готовых к употреблению процедур, оттранслированных в объектные файлы и собранных в большую кучу под названием «библиотека». #9. Посмотрите внимательно на тело WinMain. Там есть команда call, то есть вызов подпрограммы. А где, спрашивается, сама подпрограмма ExitProcess? Ан нету ее! А почему тогда, спрашивается, транслятор на это не ругается? А вы удалите строчку ExitProcess PROTO :DWORD и попробуйте оттранслировать свой исходник. Ага, хорошо знакомое: «undefined symbol : ExitProcess»? Еще бы, такой подпрограммы в нашем исходнике действительно нет! #10. Как известно, каждая программа состоит из кода и данных. Раньше мы их называли сегментами — это было связано с тем, что из-за сегментной адресации приходилось мерить мир «спичками» по 64 Кб. Теперь же мы, слава Богу, имеем единое адресное пространство, и термин сегмент, во избежание терминологической путаницы наподобие «говорим сегмент, подразумеваем 64 Кб», заменим на термин «секция», хотя, по большому счету, это одно и то же. #11. В секции кода у нас есть одна-единственная процедурка. На всякий случай напомню, что о ее начале свидетельствует строчка WinMain PROC, где WinMain — это «имя собственное», которое вы можете заменить любым словом, в том числе и своим любимым. А ее конец — это строчка WinMain ENDP. Кстати, настоящим ассемблерщикам должно быть приятно, что, опустив ненужную в связи с этим команду ret, мы сэкономили аж 4 байта кода! #12. Как я уже говорил в п.7, вызов функций API из программы на ассемблере подчиняется соглашению «stdcall». Выражаясь официозно, «с точки зрения прикладного программиста, с учетом специфики Windows и MASM», эти соглашения заключаются в следующем: #13. И, напоследок, топик #13 Assembler & win32 курс молодого бойцаПрограммирование на Ассемблере я начинал с Turbo Assembler (TASM) под MS-DOS, сейчас пишу на Flat Assembler (FASM) под Windows. Это очень удобный и мощный пакет для разработки, бесплатный для любого использования. Написан полностью на самом себе, исходники прилагаются. Мне он нравится тем, что позволяет хранить код и описания ресурсов в одном ASM-файле, поддерживает макросы, генерит чистый машинный код без всякой незаявленной самодеятельности, не требует лишней рутинной работы типа прописывания каждой задействованной функции в секцию импорта и еще множество приятных мелочей, облегчающих жизнь программисту. Единственным недостатком является отсутствие достаточного количества готовых исходников, например по сравнению с тем же MASM’ом, а портирование исходников с других платформ на FASM иногда вызывает затруднения. Но на мой взгляд портирование, в отличие от копирования, помогает гораздо лучше изучить язык. Несколько исходников-примеров есть в самом дистрибутиве FASM, еще несколько примеров можно скачать с офсайта или поискать в Интернете. Ответы на многие возникающие вопросы можно найти на официальном форуме FASM. Форум англоязычный, но на нем немало наших соотечественников. К новичкам на форуме относятся хорошо и отвечают даже на самые глупые вопросы. Для установки Flat Assembler скачайте дистрибутив с офсайта (около 800 килобайт). На момент публикации версия FASM 1.67.27, если ссылка изменится, то можете посмотреть обновление на странице загрузки. Там же можно скачать версии FASM для Linux, Unix и MS-DOS. Бесплатный add-on FASMARM к FASM для работы с ARM можно найти здесь, текущая версия FASMARM 1.12. Инсталлятора нет, программа устанавливается простым извлечением из архива в какое-нибудь удобное для вас место, например C:\FASM. Обязательно скачайте справочник Microsoft Win32 Programmer’s Reference, распакуйте его в папку с FASM’ом. Для удобства можно сделать вложенную папку \help. Microsoft Win32 Programmer’s Reference Техническую документацию по FASM на английском языке можно скачать с офсайта, на русском языке есть вот такие мануалы: Основной мануал Flat Assembler 1.64 Руководство по препроцессору FASM FASM 1.64: Руководство программиста Для продвинутых программистов могу порекомендовать справочник Windows NT/2000 Native API Reference на английском языке: Windows NT/2000 Native API Reference Для общего развития можно почитать книги Ассемблер для процессоров Intel Pentium (автор Ю.С.Магда) и Ассемблер для DOS, Windows и Unix (автор С.В.Зубков), Ассемблер & Win32. Курс молодого бойца (автор и составитель Р.Аблязов), Intel Hex Opcodes And Mnemonics — общее описание ассемблерных команд Intel 80486, x86 Instruction Set Reference — перечень и описание команд x86 процессора. Ассемблер для процессоров Intel Pentium Ассемблер для DOS, Windows и Unix Ассемблер & Win32. Курс молодого бойца Учебник по основам языка Ассемблера Учебник по языку Ассемблер в задачах и примерах Intel Hex Opcodes And Mnemonics x86 Instruction Set Reference И напоследок две книги из категории «must have». Их, конечно, лучше иметь в бумажном варианте в качестве настольных справочников, но электронные версии тоже вполне подойдут. Книги залиты на файлообменник. Обе книги на русском языке, в хорошем качестве. Соломон Д., Руссинович М. — «Внутреннее устройство Microsoft Windows 2000. Мастер-класс», формат файла: PDF, размер архива 34 Мб. Скачать Соломон Д., Руссинович М. — «Внутреннее устройство Microsoft Windows: Windows Server 2003, Windows XP, and Windows 2000», формат файла: DjVu, размер архива 27 Мб. Скачать При первом запуске FASM создаст файл настроек FASMW.INI, откройте его для редактирования в Блокноте. В конец файла надо будет добавить две новых секции. Сперва пропишите полный путь к Win32 Programmer’s Reference: [Help] Это же можно сделать и через меню редактора Help — Pick help file. Теперь, если все сделано правильно, достаточно установить в редакторе курсор на название функции API и нажать F1. Справочник сразу откроется на описании этой функции. После этого надо установить необходимые переменные окружения и пути для подключаемых файлов. Например у меня прописаны вот такие: [Environment] Переменная include обязательная, остальные для удобства. Теперь при написании программ вместо абсолютных путей можно (и нужно) использовать относительные: Список ресурсов для изучения АссемблераДоброго времени суток! … но оказалось, что найти материал по интересующей теме не так просто, как хотелось бы. Посему решено было создать на хабре пополняющийся пост-индекс статей/книг/мануалов/etc. об этом, несомненно, великом языке. UPD Для начала
РесурсыКнигиДля книг я выкладываю только названия, без ссылок (или с ссылкой на интернет-магазин), так как я не знаю отношения некоторых людей к скачиванию чьей-то интеллектуальной собственности. Кому надо — тот найдет, где скачать.
Англоязычные ресурсыИнструменты
Программинг микроконтроллеров
Прочее
ЗаключениеНадеюсь эта статья будет полезна как новичкам, так и тем, кто ищет новых знаний. Если вы знаете какие-либо интересные ресурсы по теме, смело пишите в комментарии, пост создавался, чтобы пополняться. Assembler & win32 курс молодого бойцаПрограммирование на ассемблере под Win32 воспринимается весьма не однозначно. Считается, что написание приложений слишком сложно для применения ассемблера. Собственно обсуждению того, насколько оправдана такая точка зрения, и посвящена данная статья. Она не ставит своей целью обучение программированию под Win32 или обучение ассемблеру, я подразумеваю, что читатели имеют определённые знания в этих областях. В отличие от программирования под DOS, где программы, написанные на языках высокого уровня (ЯВУ) были мало похожи на свои аналоги, написанные на ассемблере, приложения под Win32 имеют гораздо больше общего. В первую очередь, это связано с тем, что обращение к сервису операционной системы в Windows осуществляется посредством вызова функций, а не прерываний, что было характерно для DOS. Здесь нет передачи параметров в регистрах при обращении к сервисным функциям и, соответственно, нет и множества результирующих значений возвращаемых в регистрах общего назначения и регистре флагов. Следовательно, проще запомнить и использовать протоколы вызова функций системного сервиса. С другой стороны, в Win32 нельзя непосредственно работать с аппаратным уровнем, чем «грешили» программы для DOS. Вообще написание программ под Win32 стало значительно проще и это обусловлено следующими факторами:
Современный ассемблер, к которому относится и TASM 5.0 фирмы Borland International Inc., в свою очередь, развивал средства, которые ранее были характерны только для ЯВУ. К таким средствам можно отнести макроопределение вызова процедур, возможность введения шаблонов процедур (описание прототипов) и даже объектно-ориентированные расширения. Однако, ассемблер сохранил и такой прекрасный инструмент, как макроопределения вводимые пользователем, полноценного аналога которому нет ни в одном ЯВУ. Все эти факторы позволяют рассматривать ассемблер, как самостоятельный инструмент для написания приложений под платформы Win32 (Windows NT и Windows 95). Как иллюстрацию данного положения, рассмотрим простой пример приложения, работающего с диалоговым окном. Файл, содержащий текст приложения, dlg.asm IDEAL %NOINCL MAX_USER_NAME = 20 CodeSeg public stdcall DlgProc mov eax,[@@wPar] call GetDlgItemTextA, @@hDlg, > @@cancel: call EndDialog, @@hDlg, eax @@ret_false: xor eax,eax @@init: call GetDlgItem, @@hDlg, IDR_NAME Сразу после метки Start, программа обращается к функции API Win32 GetModuleHandle для получения handle данного модуля (данный параметр чаще именуют как handle of instance). Получив handle, мы вызываем диалог, созданный либо вручную, либо с помощью какой-либо программы построителя ресурсов. Далее программа проверяет результат работы диалогового окна. Если пользователь вышел из диалога посредством нажатия клавиши OK, то приложение запускает MessageBox с текстом приветствия. Диалоговая процедура обрабатывает следующие сообщения. При инициализации диалога (WM_INITDIALOG) она просит Windows установить фокус на поле ввода имени пользователя. Сообщение WM_COMMAND обрабатывается в таком порядке: делается проверка на код нажатия клавиши. Если была нажата клавиша OK, то пользовательский ввод копируется в переменную szValue, если же была нажата клавиша Cancel, то копирования не производится. Но и в том и другом случае вызывается функция окончания диалога: EndDialog. Остальные сообщения в группе WM_COMMAND просто игнорируются, предоставляя Windows действовать по умолчанию. Вы можете сравнить приведённую программу с аналогичной программой, написанной на ЯВУ, разница в написании будет незначительна. Очевидно те, кто писал приложения на ассемблере под Windows 3.x, отметят тот факт, что исчезла необходимость в сложном и громоздком startup коде. Теперь приложение выглядит более просто и естественно. Написание динамических библиотек под Win32 также значительно упростилось, по сравнению с тем, как это делалось под Windows 3.x. Исчезла необходимость вставлять startup код, а использование четырёх событий инициализации/деинициализации на уровне процессов и потоков, кажется логичным. Рассмотрим простой пример динамической библиотеки, в которой всего одна функция, преобразования целого числа в строку в шестнадцатеричной системе счисления. Ideal extrn GetVersion: proc DataSeg CodeSeg @@1: mov eax,1 public stdcall Hex2Str @@1: mov edx,eax @@3: mov [byte ebx + ecx],dl Процедура libEntry является точкой входа в динамическую библиотеку, её не надо объявлять как экспортируемую, загрузчик сам определяет её местонахождение. LibEntry может вызываться в четырёх случаях:
В нашем примере обрабатывается только первое из событий DLL_PROCESS_ATTACH. При обработке данного события библиотека запрашивает версию OS сохраняет её, а также свой handle of instance. Библиотека содержит только одну экспортируемую функцию, которая собственно не требует пояснений. Вы, пожалуй, можете обратить внимание на то, как производится запись преобразованных значений. Интересна система адресации посредством двух регистров общего назначения: ebx + ecx, она позволяет нам использовать регистр ecx одновременно и как счётчик и как составную часть адреса. Ideal struc WndClassEx struc Point struc msgStruc MyMenu = 0065 CS_VREDRAW = 0001 PROCTYPE ptGetModuleHandle stdcall PROCTYPE ptLoadIcon stdcall PROCTYPE ptLoadCursor stdcall PROCTYPE ptLoadMenu stdcall PROCTYPE ptRegister > stdcall PROCTYPE ptCreateWindowEx stdcall PROCTYPE ptShowWindow stdcall PROCTYPE ptUpdateWindow stdcall PROCTYPE ptGetMessage stdcall PROCTYPE ptTranslateMessage stdcall PROCTYPE ptDispatchMessage stdcall PROCTYPE ptSetMenu stdcall PROCTYPE ptPostQuitMessage stdcall PROCTYPE ptDefWindowProc stdcall PROCTYPE ptSendMessage stdcall PROCTYPE ptMessageBox stdcall PROCTYPE ptExitProcess stdcall extrn GetModuleHandleA :ptGetModuleHandle UDataSeg IFNDEF VER1 DataSeg CodeSeg sub esp,SIZE Wnd > ; отведём место в стеке под структуру mov [(WndClassEx esp).cbSize],SIZE WndClassEx add esp,SIZE Wnd > ; восстановим стек IFDEF VER3 msg_loop: public stdcall WndProc @@default: @@command: @@open: mov eax, offset msg_open_txt @@save: mov eax, offset msg_save_txt @@mess: call MessageBoxA, 0, eax, edx, MB_OK Здесь мне хотелось в первую очередь продемонстрировать использование прототипов функций API Win32. Конечно их (а также описание констант и структур из API Win32) следует вынести в отдельные подключаемые файлы, поскольку, скорее всего Вы будете использовать их и в других программах. Описание прототипов функций обеспечивает строгий контроль со стороны компилятора за количеством и типом параметров, передаваемых в функции. Это существенно облегчает жизнь программисту, позволяя избежать ошибок времени исполнения, тем более, что число параметров в некоторых функциях API Win32 весьма значительно. Существо данной программы заключается в демонстрации вариантов работы с оконным меню. Программу можно откомпилировать в трёх вариантах (версиях), указывая компилятору, ключи VER2 или VER3 (по умолчанию используется ключ VER1). В первом варианте программы меню определяется на уровне класса окна, и все окна данного класса будут иметь аналогичное меню. Во втором варианте, меню определяется при создании окна, как параметр функции CreateWindowEx. Класс окна не имеет меню и в данном случае, каждое окно этого класса может иметь своё собственное меню. Наконец, в третьем варианте, меню загружается после создания окна. Данный вариант показывает, как можно связать меню с уже созданным окном. Директивы условной компиляции позволяют включить все варианты в текст одной и той же программы. Подобная техника удобна не только для демонстрации, но и для отладки. Например, когда Вам требуется включить в программу новый фрагмент кода, то Вы можете применить данную технику, дабы не потерять функционирующий модуль. Ну, и конечно, применение директив условной компиляции — наиболее удобное средство тестирования различных решений (алгоритмов) на одном модуле. Представляет определённый интерес использование стековых фреймов и заполнение структур в стеке посредством регистра указателя стека (esp). Именно это продемонстрировано при заполнении структуры WndClassEx. Выделение места в стеке (фрейма) делается простым перемещением esp: Теперь мы можем обращаться к выделенной памяти, используя всё тот же регистр указатель стека. При создании 16-битных приложений такой возможностью мы не обладали. Данный приём можно использовать внутри любой процедуры или даже произвольном месте программы. Накладные расходы на подобное выделение памяти минимальны, однако, следует учитывать, что размер стека ограничен, и размещать большие объёмы данных в стеке вряд ли целесообразно. Для этих целей лучше использовать «кучи» (heap) или виртуальную память (virtual memory). Остальная часть программы достаточно тривиальна и не требует каких-либо пояснений. Возможно, более интересным покажется тема использования макроопределений. Мне достаточно редко приходилось серьёзно заниматься разработкой макроопределений при программировании под DOS. В Win32 ситуация принципиально иная. Здесь грамотно написанные макроопределения способны не только облегчить чтение и восприятие программ, но и реально облегчить жизнь программистов. Дело в том, что в Win32 фрагменты кода часто повторяются, имея при этом не принципиальные отличия. Наиболее показательна, в этом смысле, оконная и/или диалоговая процедура. И в том и другом случае мы определяем вид сообщения и передаём управление тому участку кода, который отвечает за обработку полученного сообщения. Если в программе активно используются диалоговые окна, то аналогичные фрагменты кода сильно перегрузят программу, сделав её малопригодной для восприятия. Применение макроопределений в таких ситуациях более чем оправдано. В качестве основы для макроопределения, занимающегося диспетчеризацией поступающих сообщений на обработчиков, может послужить следующее описание. macro MessageVector message1, message2:REST macro WndMessages VecName, message1, message2:REST @@&VecName&_1: dec ecx @@default: call DefWindowProcA, [@@hWnd], [@@msg], [@@wPar], [@@lPar] @@ret_false: xor eax,eax @@ret_true: mov eax,-1 При написании процедуры окна Вы можете использовать макроопределение WndMessages, указав в списке параметров те сообщения, обработку которых намерены осуществить. Тогда процедура окна примет вид: proc WndProc stdcall @@WM_CREATE: @@WM_SIZE: @@WM_PAINT: @@WM_CLOSE: @@WM_DESTROY: Обработку каждого сообщения можно завершить тремя способами:
Отметьте, что все перечисленные метки определены в макро WndMessages и Вам не следует определять их заново в теле процедуры. Теперь давайте разберёмся, что происходит при вызове макроопределения WndMessages. Вначале производится обнуление счётчика параметров самого макроопределения (число этих параметров может быть произвольным). Теперь в сегменте данных создадим метку с тем именем, которое передано в макроопределение в качестве первого параметра. Имя метки формируется путём конкатенации символов @@ и названия вектора. Достигается это за счёт использования оператора &. Например, если передать имя TestLabel, то название метки примет вид: @@TestLabel. Сразу за объявлением метки вызывается другое макроопределение MessageVector, в которое передаются все остальные параметры, которые должны быть ничем иным, как списком сообщений, подлежащих обработке в процедуре окна. Структура макроопределения MessageVector проста и бесхитростна. Она извлекает первый параметр и в ячейку памяти формата dword заносит код сообщения. В следующую ячейку памяти формата dword записывается адрес метки обработчика, имя которой формируется по описанному выше правилу. Счётчик сообщений увеличивается на единицу. Далее следует рекурсивный вызов с передачей ещё не зарегистрированных сообщений, и так продолжается до тех пор, пока список сообщений не будет исчерпан. Сейчас в макроопределении WndMessage можно начинать обработку. Теперь существо обработки, скорее всего, будет понятно без дополнительных пояснений. Обработка сообщений в Windows не является линейной, а, как правило, представляет собой иерархию. Например, сообщение WM_COMMAND может заключать в себе множество сообщений поступающих от меню и/или других управляющих элементов. Следовательно, данную методику можно с успехом применить и для других уровней каскада и даже несколько упростить её. Действительно, не в наших силах исправить код сообщений, поступающих в процедуру окна или диалога, но выбор последовательности констант, назначаемых пунктам меню или управляющим элементам (controls) остаётся за нами. В этом случае нет нужды в дополнительном поле, которое сохраняет код сообщения. Тогда каждый элемент вектора будет содержать только адрес обработчика, а найти нужный элемент весьма просто. Из полученной константы, пришедшей в сообщении, вычитается идентификатор первого пункта меню или первого управляющего элемента, это и будет номер нужного элемента вектора. Остаётся только сделать переход на обработчик. Вообще тема макроопределений весьма поучительна и обширна. Мне редко доводится видеть грамотное использование макросов и это досадно, поскольку с их помощью можно сделать работу в ассемблере значительно проще и приятнее. Masm32 для чайников |
25.07.2014, 22:25 | ||
Деление для чайников Ошибки MASM32 — cannot open file : .\masm32\include\windows.inc Ассемблер под Windows для чайников (MASM32 Editor) для новичков Компиляция программ для DOS в MASM32 |
|||
26.07.2014, 00:21 | 2 | ||
Ассемблер для процессоров Intel Pentium Начни правильно, бери FASM. Синтаксис более лаконичный чем у остальных в частности и у masm32. |
|||
27.07.2014, 10:39 | 3 | ||
|
|||
27.07.2014, 14:42 | 4 | ||
27.07.2014, 15:17 | 5 | ||
30.07.2014, 09:43 | 6 | ||
|