КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Основы 32-битного программирования в Windows
Двум стадиям трансляции соответствуют две основные программы: ассемблер ML.EXE и редактор связей LINK.EXE. Пусть файл с текстом программы на языке ассемблера называется PROG.ASM, тогда две стадии трансляции будут выглядеть следующим образом: · Стадия 1 - в результате появляется модуль PROG.OBJ. · Стадия 2 - в результате появляется исполняемый модуль PROG.EXE. Формат конечного модуля зависит от операционной системы. Установив стандарт на структуру объектного модуля, мы получаем возможность: · использовать уже готовые объектные модули, · стыковать между собой программы, написанные на разных языках. Если стандарт объектного модуля распространить на разные операционные системы, то можно использовать модули, написанные в разных операционных системах. Приведем обзор ряда программ, которые часто используются при программировании на ассемблере. Редакторы QEDITOR.EXE поставляется вместе с пакетом MASM32. Сам редактор и все сопутствующие ему утилиты написаны на ассемблере. Анализ их размера и возможностей действительно впечатляет. Например, сам редактор имеет длину всего 27 Кб, а утилита, используемая для просмотра отчетов о трансляции — всего 6 Кб. Редактор вполне годится для работы с небольшими одномодульными приложениями. Для работы с несколькими модулями он не очень удобен. Работа редактора основана на взаимодействии с различными утилитами посредством пакетных файлов. Например, трансляцию программ осуществляет пакетный файл ASSMBL.BAT, который использует ассемблер ML.EXE, а результат ассемблирования направляется в текстовый файл ASMBL.TXT. Далее для просмотра этого файла используется простая утилита THEGUN.EXE. Аналогично осуществляется редактирование связей. Для дизассемблирования исполняемого модуля используется утилита DUMPPE.EXE, результат работы этой утилиты помещается в текстовый файл DISASM.TXT. Вторая программа это EAS.EXE (Easy Assembler Shell). Редактор, а точнее оболочка, позволяет создавать и транслировать довольно сложные проекты, состоящие из ASM-,OВJ-,RC-,RES-,DEF-файлов. Программа позволяет работать как с TASM, так и MASM, а также с другими утилитами (отладчиками, редакторами ресурсов и т.д.). Непосредственно в программе можно настроить компиляторы и редакторы связей на определенный режим работы путем задания ключей этих утилит. Отладчики. Отладчики позволяют исполнять программу в пошаговом режиме. Несколько наиболее известных отладчиков CodeView (Микрософт), Turbo Debugger (Borland), Ice. Дизассемблеры. Дизассемблеры переводят исполняемый модуль в ассемблерный код. Примером простейшего дизассемблера является программа DUMPPE.EXE, работающая в строковом режиме. Отметим также дизассемблер W32Dasm и знаменитый дизассемблер IDA Pro. Нех-редакторы. Нех-редакторы позволяют просматривать и редактировать загружаемые модули в шестнадцатеричном виде. Их великое множество, к тому же отладчики и дизассемблеры, как правило, имеют встроенные НЕХ-редакторы.. Редакторы ресурсов. Ресурсы - это готовые шаблоны, которые можно включать в коды. Простые ресурсы можно создавать в обычном текстовом редакторе. Компиляторы ресурсов. Они превращают текст ресурса в модуль. В пакетах MASM32 и TASM32 есть компиляторы ресурсов. Это программы RC.EXE и BRC32.EXE соответственно. Для начала программирования на ассемблере в среде Windows важны два момента: · Вызов системных функций API (Application Program Interface, т.е. интерфейс программного приложения). · Возможные структуры программ для Windows. Можно выделить 3 типа структуры программ - классическая, диалоговая (основное окно — диалоговое), консольная (или безоконная)структура.
Программирование в Windows основывается на использовании функций API. Их количество достигает двух тысяч. Ваша программа в значительной степени будет состоять из таких вызовов. Все взаимодействие с внешними устройствами и ресурсами операционной системы будет происходить посредством таких функций. · Список функций API и их описание лучше всего брать из файла WIN32.HLP, который поставляется, например, с пакетом Borland C++. · Главным элементом программы в среде Windows является окно. Для каждого окна определяется своя процедура обработки сообщений. · Окно может содержать элементы управления: кнопки, списки, окна редактирования и др. Эти элементы, по сути, также являются окнами, но обладающими особыми свойствами. События, происходящие с этими элементами (и самим окном), приводят к приходу сообщений в процедуру окна. · Операционная система Windows использует линейную модель памяти. То есть, всю память можно рассматривать как один сегмент. Для программиста на языке ассемблера это означает, что адрес любой ячейки памяти будет определяться содержимым одного 32-битного регистра, например EBX. · Мы фактически не ограничены в объеме данных, кода или стека (объеме локальных переменных). Выделение в тексте программы сегмента кода и сегмента данных является теперь простой формальностью, улучшающей читаемость программы. · Операционная система Windows является многозадачной средой. Каждая задача имеет свое адресное пространство и свою очередь сообщений. Более того, даже в рамках одной программы может быть осуществлена многозадачность - любая процедура может быть запущена как самостоятельная задача. Начнем с того, как можно вызвать функции API, например, MessageBox. Это ее синтаксис: int MessageBox (HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); Данная функция выводит на экран окно с сообщением и кнопкой (или кнопками) выхода. Для каждого аргумента определены тип (32-битные целые числа) и значение: · hWnd -дескриптор окна, в котором будет появляться окно-сообщение, тип HWND — 32-битное целое. · lpText - текст, который будет появляться в окне, тип LPCTSTR — 32-битный указатель на строку. · lpCaption - текст в заголовке окна, тип LPCTSTR — 32-битный указатель на строку. · uType - тип окна, в частности можно определить количество кнопок выхода. Тип UINT — 32-битное целое. К имени функций нужно добавлять суффикс "А" при использовании кодировки символов ANSI, кроме того, при использовании MASM необходимо также в конце имени добавить @16. Вызов указанной функции будет выглядеть так: CALL MessageBoxA@16. Аргументы будут извлекаться из стека в порядке их упоминанию в функции. Чтобы это было возможно надлежит ввести в стек до вызова функции в обратном порядке. Пример для MessageBox. ; Создать аргументы МВ_ОК equ 0; uType создать STR1 DB "Неверный ввод! ",0; lpText создать STR2 DB "Сообщение об ошибке.",0; lpCaption создать HW DWORD?; hwind создать ; Поместить аргументы в стек
PUSH МВ_ОК; uType в стек PUSH OFFSET STR2; lpCaption в стек PUSH OFFSET STR1; lpText в стек PUSH HW; hwind в стек
CALL MessageBoxA@16; вызов функции Теперь обратимся к структуре всей программы.В классической структуре программы под Windows имеется главное окно, а следовательно, и процедура главного окна. В целом, в коде программы можно выделить следующие секции: · Регистрация класса окон. · Создание главного окна. · Цикл обработки очереди сообщений. · Процедура главного окна. Регистрация класса окон. Регистрация класса окон осуществляется с помощью функции RegisterClassA, единственным параметром которой является указатель на структуру WNDCLASS, содержащую информацию об окне (см. пример ниже). Создание окна. На основе зарегистрированного класса с помощью функции CreateWindowExA (или CreateWindowA) можно создать экземпляр окна. Цикл обработки очереди сообщений. В нем используются функции: · GetMessage(), которая "отлавливает" очередное сообщение из ряда сообщений данного приложения и помещает его в структуру MSG. · TranslateMessage, которая используется для сообщений WM_KEYDOWN и WM_KEYUP, которые транслируются в WM_CHAR и WM_DEADCHAR, · а также WM_SYSKEYDOWN и WM_SYSKEYUP, преобразующиеся в WM_SYSCHAR и WM_SYSDEADCHAR. Смысл трансляции заключается не в замене, а в отправке дополнительных сообщений. Так, например, при нажатии и отпускании алфавитно-цифровой клавиши в окно сначала придет сообщение WM_KEYDOWN, затем WM_KEYUP, а затем уже WM_CHAR. Выход из цикла ожиданий имеет место только в том случае, если функция GetMessage возвращает 0. Это происходит только при получении сообщения о выходе (сообщение WM_QUIT). Таким образом, цикл ожидания играет двоякую роль: определенным образом преобразуются сообщения, предназначенные для какого-либо окна, и ожидается сообщение о выходе из программы. Процедура главного окна. Используется функция WindowFunc. Ее прототип на языке C WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) Для каждого аргумента определены тип (32-битные целые числа) и значение: · hWnd - дескриптор окна, в котором будет появляться окно-сообщение, тип HWND — 32-битное целое. · Message – идентификатор сообщения. Тип UINT — 32-битное целое. · WPARAM – уточнение. Тип wParam — 32-битное целое. · LPARAM - уточнение. Тип lParam — 32-битное целое.. Рассмотрим "скелет" этой функции на языке ассемблера. ; Создать аргументы МВ_ОК equ 0; uType создать STR1 DB "Неверный ввод! ",0; lpText создать STR2 DB "Сообщение об ошибке.",0; lpCaption создать HW DWORD?; hwind создать WNDPROC PROC; определение функции WndProc PUSH EBP; получить адрес вершины стека MOV EBP, ESP; теперь EBP указывает на вершину стека ; поместить в стек контекст предыдущей программы PUSH EBX PUSH ESI PUSH EDI ; поместить в стек аргументы функции окна через регистр EBP PUSH DWORD PTR [EBP+14H]; LPARAM (lParam) в стек PUSH DWORD PTR [EBP+10H]; WPARAM (wParam) в стек PUSH DWORD PTR [EBP+0CH]; MES (message) в стек PUSH DWORD PTR [EBP+08H]; HWND (hwnd) в стек CALL DefWindowProcA@16; вызов внешней функции окна ; вернуть из стека контекст предыдущей программы (в обратном порядке) POP EDI POP ESI POP EBX POP EBP RET 16; выход из функции освобождением стека от четырех параметров (16=4*4). WNDPROC ENDP; конец функции WndProc
Дата добавления: 2014-10-23; Просмотров: 447; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |