Макросредства ассемблера в Windows

Тип работы:
Курсовая
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

1. Содержание

1. Содержание

2. Введение

3. Описание использованного набора макросредств.

4. Использованные API-функции и системные константы.

4.1 Список использованных констант и структур.

4.2 Список использованных API-функций.

4.3 Основы вызова API-функций

5. Демонстрационная программа

5.1 Листинг

5.2 Результат работы программы

6. Вывод

2. Введение

Целью курсовой работы является изучение основ программирования на 32-битном ассемблере, при помощи которого необходимо разработать программу, демонстрирующую работу одного из разделов ОС WINDOWS.

В данном отчете отражена работа макросредств ассемблера в WINDOWS. На основании описанных функций разработана программа, иллюстрирующая возможности макросредств.

Первый вопрос, который задает себе человек, впервые услышавший об ассемблере, — а зачем он, собственно, нужен? Особенно теперь, когда все пишут на C/C++, Delphi или других языках высокого уровня? Действительно очень многое можно создать на С, но ни один язык, даже такой популярный, не может претендовать на то, чтобы на нем можно было написать абсолютно все.

Итак, на ассемблере пишут:

· все, что требует максимальной скорости выполнения: основные компоненты компьютерных игр, ядра операционных систем реального времени и просто критические участки программ;

· все, что взаимодействует с внешними устройствами: драйверы, программы, работающие напрямую с портами, звуковыми и видеоплатами;

· все, что использует полностью возможности процессора: ядра многозадачных операционных систем, DPMI-серверы и вообще любые программы, переводящие процессор в защищенный режим;

· все, что полностью использует возможности операционной системы: вирусы и антивирусы, защиты от несанкционированного доступа, программы, обходящие эти защиты, и программы, защищающиеся от данных программ;

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

Большинство операционных систем написано преимущественно на языке ассемблера. Поэтому операционную систему Windows нагляднее изучать, используя именно этот язык.

Одно из самых мощных языковых средств ассемблера — макроопределения.

Макроопределением (или макросом) называется участок программы, которому присвоено имя и который ассемблируется всякий раз, когда ассемблер встречает это имя в тексте программы. Макрос начинается директивой MACRO и заканчивается ENDM.

Например: пусть описано макроопределение hex2ascii, переводящее шестнадцатеричное число, находящееся в регистре AL, в ASCII-код соответствующей шестнадцатеричной цифры:

hex2ascii macro

cmp al, 10

sbb al, 69h

das

endm

макросреда ассемблер программа текст

Сейчас в программе можно использовать слово hex2ascii, как если бы это было имя команды, и ассемблер заменит каждое такое слово на три команды, содержащиеся в макроопределении. Разумеется, можно оформить этот же участок кода в виде процедуры и вызывать его командой CALL — если процедура вызывается больше одного раза, этот вариант программы займет меньше места, но вариант с макроопределением станет выполняться быстрее, так как в нем не будет лишних команд CALL и RET. Однако скорость выполнения — не главное преимущество макросов. В отличие от процедур макроопределения могут вызыватьсяс параметрами.

Транслятор ассемблера состоит из двух частей -- непосредственно транслятора, формирующего объектный модуль, и макроассемблера (рис. 1).

Рис. 1. Макроассемблер в общей схеме трансляции программы на TASM

Таким образом, обработка программы на ассемблере с использованием макросредств неявно осуществляется транслятором в две фазы (рис. 1).

На первой фазе работает часть компилятора, называемая макроассемблером.

На второй фазе трансляции работает непосредственно ассемблер, задачей которого является формирование объектного кода, содержащего текст исходной программы в машинном виде.

3. Описание использованного набора макросредств

3.1 Псевдооператор equ

Этот псевдооператор предназначен для присвоения некоторому выражению символического имени или идентификатора. Впоследствии, когда в ходе трансляции этот идентификатор встретится в телепрограммы, макроассемблер подставит вместо него соответствующее выражение.

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

3.2 Структура

Директива STRUC позволяет объединить несколько разнородных данных в одно целое. Эти данные называются полями. Вначале при помощи STRUC определяется шаблон структуры, затем с помощью директивы < > можно определить любое количество структур. Рассмотрим пример:

STRUC COMPLEX

RE DD ?

IM DD ?

STRUC ENDS

;в сегменте данных

COMP1 COMPLEX < ?>

COMP2 COMPLEX < ?>

3.3 Условное ассемблирование

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

а)

IF выражение

ENDIF

б)

IF выражение

ELSE

ENDIF

в)

IF выражение 1

ELSEIF выражение 2

ELSEIF выражение 3

ELSE

ENDIF

Условие считается

3.4 Макроповторения

1. Повторение, заданное определенное число раз. Используется макродиректива REPT. Например:

A EQU 10

REPT 100

DB A

ENDM

Будет сгенерировано 100 директив DB 10.

2. Директива IRP.

IRP параметр,< список>

ENDM

Блок будет вызываться столько раз, сколько параметров в списке. Например:

IRP REG, < EAX, EBX, ECX, EDX, ESI, EDI>

PUSH REG

ENDM

Приведет к генерации следующих строк:

PUSH EAX

PUSH EBX

PUSH ECX

PUSH EDX

PUSH ESI

PUSH EDI

4. Использованные API-функции и системные константы

4. 1 Список использованных констант и структур

Сообщения:

WM_SETFOCUS equ 7h — Сообщение, посылаемое окну, после того, как оно получило фокус.

WM_DESTROY equ 2 — Завершить приложение.

WM_CREATE equ 1 — Создать окно.

WM_PAINT equ 0FH — Отрисовка окна из буфера.

WM_COMMAND equ 111h — Сообщение, приходящее на функцию окна, при наступлении события с управляющим элементом, пунктом меню, а также от акселератора.

WM_SETTEXT equ 0Ch — Сообщение, используемое приложением для посылки текстовой строки окну и интерпретируемое в зависимости от типа окна (обычное окно — заголовок, кнопка -- надпись на кнопке, окно редактирования — содержимое этого окна и т. д.).

WM_GETTEXT equ 0Dh — Посылается окну для получения текстовой строки, ассоциированной с данным окном (строка редактирования, заголовок окна и т. д.).

Стили окна:

CS_VREDRAW equ 1h — Посылка WM_PAINT при изменении.

CS_HREDRAW equ 2h — Размеров окна.

CS_GLOBALCLASS equ 4000h — Класс окна.

WS_OVERLAPPEDWINDOW equ 000CF0000H — Стиль окна.

Интерфейс:

IDI_APPLICATION equ 32 512 — Иконка

IDC_ARROW equ 32 512 — Курсор

SW_SHOWNORMAL equ 1 — Режим

показа окна

Структуры:

WNDCLASS STRUC — Класс окна

CLSSTYLE DD? -Стиль окна

CLWNDPROC DD? — Основная оконная процедура

CLSCBCLSEX DD? — Пространство для данных

CLSCBWNDEX DD? — Пространство для структур

CLSHINST DD? — Определение класса

CLSHICON DD? — Иконка

CLSHCURSOR DD? — Курсор

CLBKGROUND DD? — Фон

CLMENNAME DD? -Имя окна

CLNAME DD? — Имя класса

WNDCLASS ENDS

PAINTSTR STRUC — Окраска клиентской области

hdc DD 0 — Указатель на контекст устройства

fErase DD 0 — Стирать ли фон при перерисовке?

left DD 0 — Координаты прямоугольника

top DD 0 — Окна для рисования

right DD 0 — Правая граница

bottom DD 0 — Нижняя граница

fRes DD 0 — Зарезервировано Windows

fIncUp DD 0 — Зарезервировано Windows

Reserv DB 32 dup (0) — Зарезервировано Windows

PAINTSTR ENDS

MSGSTRUCT STRUC — Структура сообщения

MSHWND DD? — Указатель на окно

MSMESSAGE DD? — Сообщение

MSWPARAM DD? — Дополнительная информация

MSLPARAM DD? — Дополнительная информация

MSTIME DD? — Время отправки сообщения

MSPT DD? — Позиция курсора

MSGSTRUCT ENDS

4.2 Список использованных API-функций

SetFocus — Установить фокус на заданное окно.

SendMessage — Послать сообщение окну.

CreateWindow — Создать окно.

DefWindowProc — Вызывается для сообщений, которые не обрабатываются функцией окна.

DispatchMessage — Вернуть управление Windows с передачей сообщения предназначенному окну.

ExitProcess — Закончить данный процесс со всеми подзадачами (потоками).

GetMessage — Получить очередное сообщение из очереди сообщений данного приложения.

GetModuleHandle — Получить дескриптор приложения.

LoadCursor — Загрузить системный курсор или курсор, определенный в файле ресурсов.

LoadIcon — Загрузить системную иконку или иконку, определенную в файле ресурсов.

PostQuitMessage — Послать текущему приложению сообщение WM_QUIT.

RegisterClass — Зарегистрировать класс окон.

ShowWindow — Показать окно, установить статус показа.

TranslateMessage — Транслировать клавиатурные сообщения в ASCII-коды.

UpdateWindow — Обновить рабочую область окна.

BeginPaint — Получить контекст при получении сообщения WM_PAINT

EndPaint — Удалить контекст, полученный при помощи BeginPaint.

TextOut — Вывести текст в окно.

SetBkColor — Установить цвет фона для вывода текста.

InvalidateRect — Перерисовать окно.

4.3 Основы вызова API-функций

Функции API в ассемблере вызываются способом, схожим с вызовом в языках высокого уровня. Для этого все передаваемые параметры передаются в стек в обратном порядке.

Например, функция:

SendMessage (

__in HWND hWnd,

__in UINT Msg,

__in WPARAM wParam,

__in LPARAM lParam

);

будет вызвана в ассемблере по следующему шаблону:

includelibuser32. lib

EXTERNSendMessageA@16: NEAR

TEXT DB 'Введите текст', 0

HWNDEDT1 DWORD 0

-

-

PUSH OFFSET TEXT

PUSH 0

PUSH WM_SETTEXT

PUSH HWNDEDT1

CALL SendMessageA@16

В таком вызове API функции SendMessage добавляется символ А, указывающий на ANSI-стандарт, символ @ в роли разделителя и число N в конце, обозначающий количество байт информации, которая передается в функцию через стек.

Далее представим, какие параметры передаются для остальных API-функции:

HWND WINAPI SetFocus (

__in_opt HWND hWnd

);

Тип: HWND

Дескриптор окна, которое будет получать ввод с клавиатуры. Если этот параметр равен NULL, нажатия клавиш игнорируются.

HWND WINAPI CreateWindow (

__in_opt LPCTSTR lpClassName,//строка

__in_opt LPCTSTR lpWindowName,//имя окна

__in DWORD dwStyle,//стиль задаваемого окна

__in int x,//первоначальное горизонтально положение окна

__in int y,//первоначальное вертикальное положение окна

__in int nWidth, //ширина

__in int nHeight, //высота

__in_opt HWND hWndParent, //окно владельца создаваемого окна

__in_opt HMENU hMenu, //обращаться к меню

__in_opt HINSTANCE hInstance, //дескриптор

__in_opt LPVOID lpParam //указатель

);

LRESULT WINAPI DefWindowProc (

__in HWND hWnd, //дескриптор окна

__in UINT Msg, //сообщение

__in WPARAM wParam, //дополнительная информация сообщения

__in LPARAM lParam //дополнительная информация сообщения

);

LRESULT WINAPI DispatchMessage (

__in const MSG *lpmsg //указатель на структуру, содержащую сообщение

);

VOID WINAPI ExitProcess (

__in UINT uExitCode //код выхода

);

BOOL WINAPI GetMessage (

__out LPMSG lpMsg, //указатель на MSG структуру

__in_opt HWND hWnd, //дескриптор окна

__in UINT wMsgFilterMin, // целое число из самых низких сообщение значение для поиска

__in UINT wMsgFilterMax // целое значение самого высокого значения сообщения должны быть извлечены.

);

HMODULE WINAPI GetModuleHandle (

__in_opt LPCTSTR lpModuleName // имя загружаемого модуля (либо DLL или EXE-файл), если EXE файл то параметр равен NULL

);

HCURSOR WINAPI LoadCursor (

__in_opt HINSTANCE hInstance, //дескриптор экземпляра модуля

__in LPCTSTR lpCursorName //имя ресурса курсора для загрузки

);

HICON WINAPI LoadIcon (

__in_opt HINSTANCE hInstance,

__in LPCTSTR lpIconName //имя ресурса иконки для загрузки

);

VOID WINAPI PostQuitMessage (

__in int nExitCode //код выхода из приложения

);

ATOM WINAPI RegisterClass (

__in const WNDCLASS *lpWndClass //указатель на WINDCLASS структуры

);

BOOL WINAPI ShowWindow (

__in HWND hWnd, //дескриптор окна

__in int nCmdShow //как окно будет показано на экране

);

BOOL WINAPI TranslateMessage (

__in const MSG *lpMsg //указатель на MSG структуру

);

BOOL UpdateWindow (

__in HWND hWnd //обращается к окну, чтобы быть обновиться

);

HDC BeginPaint (

__in HWND hwnd, //обращается к окну, чтобы перекрасить

__out LPPAINTSTRUCT lpPaint //указатель на PAINTSTRUCT структуру

);

BOOL EndPaint (

__in HWND hWnd, //дескриптор окна, которое было перекращено

__in const PAINTSTRUCT *lpPaint // указатель на PAINTSTRUCT структуру

);

BOOL TextOut (

__in HDC hdc, //дескриптор контекста устройств

__in int nXStart, //координата Х

__in int nYStart, //коорданата Y

__in LPCTSTR lpString, //указатель на строку

__in int cchString //длина строки

);

COLORREF SetBkColor (

__in HDC hdc, //дескриптор контекста устройств

__in COLORREF crColor //новый цвет фона, используется RGB макрос

);

BOOL InvalidateRect (

__in HWND hWnd, //дескриптор окна

__in const RECT *lpRect, //указатель на RECT структуру

__in BOOL bErase //указывает будет ли фон внутри области

);

Аналогичным образом задаются структуры. Так, структуре:

typedef struct tagMSG { // msg

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

} MSG;

Соответствует код:

MSGSTRUCT STRUC

MSHWND DD ?

MSMESSAGE DD ?

MSWPARAM DD ?

MSLPARAM DD ?

MSTIME DD ?

MSPT DD ?

MSGSTRUCT ENDS

typedef struct tagWNDCLASS {

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HINSTANCE hInstance;

HICON hIcon;

HCURSOR hCursor;

HBRUSH hbrBackground;

LPCTSTR lpszMenuName;

LPCTSTR lpszClassName;

} WNDCLASS, *PWNDCLASS;

Соответствует код:

WNDCLASS STRUC

CLSSTYLE DD ?

CLWNDPROC DD ?

CLSCBCLSEX DD ?

CLSCBWNDEX DD ?

CLSHINST DD ?

CLSHICON DD ?

CLSHCURSOR DD ?

CLBKGROUND DD ?

CLMENNAME DD ?

CLNAME DD ?

WNDCLASS ENDS

typedef struct tagPAINTSTRUCT { // ps

HDC hdc;

BOOL fErase;

RECT rcPaint;

BOOL fRestore;

BOOL fIncUpdate;

BYTE rgbReserved[32];

} PAINTSTRUCT;

Соответствует код:

PAINTSTR STRUC

hdc DWORD 0

fErase DWORD 0

left DWORD 0

top DWORD 0

right DWORD 0

bottom DWORD 0

fRes DWORD 0

fIncUp DWORD 0

Reserv DB 32 dup (0)

PAINTSTR ENDS

5. Демонстрационная программа

5.1 Листинг:

Файл edit. inc:

; константы

WM_SETFOCUS equ 7h

; сообщение приходит при закрытии окна

WM_DESTROY equ 2

; сообщение приходит при содании окна

WM_CREATE equ 1

; сообщение, если что-то происходит с элементами на окне

WM_COMMAND equ 111h

; сообщение, позволяющее послать элементу строку

WM_SETTEXT equ 0Ch

WM_PAINT equ 0FH

; сообщение, позволяющее получить строку

WM_GETTEXT equ 0Dh

; компоненты цветов

RED equ 49

GREEN equ 106

BLUE equ 197

RGBW equ 195 shl 13

RGBT equ 0; черный

; свойства окна

CS_VREDRAW equ 1h

CS_HREDRAW equ 2h

CS_GLOBALCLASS equ 4000h

WS_OVERLAPPEDWINDOW equ 000CF0000H

STYLE equ CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS

; CS_HREDRAW equ 2h

BS_DEFPUSHBUTTON equ 1h

WS_VISIBLE equ 1 000 0000h

WS_CHILD equ 4 000 0000h

WS_BORDER equ 80 0000h

WS_TABSTOP equ 1 0000h

STYLBTN equ WS_CHILD + BS_DEFPUSHBUTTON + WS_VISIBLE + WS_TABSTOP

STYLEDT equ WS_CHILD + WS_VISIBLE + WS_BORDER + WS_TABSTOP

; идентификатор стандартной иконки

IDI_APPLICATION equ 32 512

; идентификатор курсора

IDC_ARROW equ 32 512;

; режим показа окна -- нормальный

SW_SHOWNORMAL equ 1

; прототипы внешних процедур

EXTERN SetFocus@4: NEAR

EXTERN SendMessageA@16: NEAR

EXTERN MessageBoxA@16: NEAR

EXTERN CreateWindowExA@48: NEAR

EXTERN DefWindowProcA@16: NEAR

EXTERN DispatchMessageA@4: NEAR

EXTERN ExitProcess@4: NEAR

EXTERN GetMessageA@16: NEAR

EXTERN GetModuleHandleA@4: NEAR

EXTERN LoadCursorA@8: NEAR

EXTERN LoadIconA@8: NEAR

EXTERN PostQuitMessage@4: NEAR

EXTERN RegisterClassA@4: NEAR

EXTERN ShowWindow@8: NEAR

EXTERN TranslateMessage@4: NEAR

EXTERN UpdateWindow@4: NEAR

EXTERN BeginPaint@8: NEAR

EXTERN EndPaint@8: NEAR

EXTERN TextOutA@20: NEAR

EXTERN GetStockObject@4: NEAR

EXTERN CreateSolidBrush@4: NEAR

EXTERN SetBkColor@8: NEAR

EXTERN SetTextColor@8: NEAR

EXTERN InvalidateRect@12: NEAR

; структуры

; структура сообщения

MSGSTRUCT STRUC

MSHWND DD ?

MSMESSAGE DD ?

MSWPARAM DD ?

MSLPARAM DD ?

MSTIME DD ?

MSPT DD ?

MSGSTRUCT ENDS

; ----структура класса окон

WNDCLASS STRUC

CLSSTYLE DD ?

CLWNDPROC DD ?

CLSCBCLSEX DD ?

CLSCBWNDEX DD ?

CLSHINST DD ?

CLSHICON DD ?

CLSHCURSOR DD ?

CLBKGROUND DD ?

CLMENNAME DD ?

CLNAME DD ?

WNDCLASS ENDS

PAINTSTR STRUC

hdc DWORD 0

fErase DWORD 0

left DWORD 0

top DWORD 0

right DWORD 0

bottom DWORD 0

fRes DWORD 0

fIncUp DWORD 0

Reserv DB 32 dup (0)

PAINTSTR ENDS

Файл edit. asm:

. 386P

; плоская модель

. MODEL FLAT, stdcall

include qq. inc

; подключение библиотек

includelib user32. lib; Модуль для поддержки пользовательского интерфейса

includelib kernel32. lib; Модуль для работы с ядром ОС

includelib gdi32. lib; Модуль для поддержки графического интерфейса

; ------------------------------------------------------------

; сегмент данных

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

NEWHWND DD 0; хэндлер окна

MSG MSGSTRUCT < ?>

WC WNDCLASS < ?>

PNT PAINTSTR < ?>

HINST DD 0; дескриптор приложения

TITLENAME DB 'Macro Assembler', 0

CLASSNAME DB 'CLASS32', 0

CPBUT DB 'Копировать', 0

CPBUT1 DB 'Повторить 20 раз с помощью REPT', 0

CPEDT DB ' ', 0

CLSBUTN DB 'BUTTON', 0

CLSEDIT DB 'EDIT', 0

TMP DB 0

HWNDBTN DWORD 0

HWNDBTN1 DWORD 0

HWNDEDT DWORD 0

HWNDEDT1 DWORD 0

XT DWORD 10

YT DWORD 90

TEXT DB 'Введите текст', 0

DB 50 DUP (0); продолжение буфера

TEXTM DB 'Строка выведена 10 раз с помощью макрокоманды REPT', 0

DB 50 DUP (0); продолжение буфера

_DATA ENDS

; сегмент кода

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

START:

; получить дескриптор приложения

PUSH 0

CALL GetModuleHandleA@4; Возвращает дескриптор модуля, содержащего тип, представленный данным экземпляром

MOV [HINST], EAX

REG_CLASS:; регистрация класса окна

; заполнить структуру окна

; стиль

MOV [WC. CLSSTYLE], STYLE

; процедура обработки сообщений

MOV [WC. CLWNDPROC], OFFSET WNDPROC

MOV [WC. CLSCBCLSEX], 0

MOV [WC. CLSCBWNDEX], 0

MOV EAX, [HINST]

MOV [WC. CLSHINST], EAX

; ---------- иконка окна

PUSH IDI_APPLICATION

PUSH 0

CALL LoadIconA@8; загружаем иконку

MOV [WC. CLSHICON], EAX

; ---------- курсор окна

PUSH IDC_ARROW

PUSH 0

CALL LoadCursorA@8; загружаем курсор

MOV [WC. CLSHCURSOR], EAX

; ----------

MOV [WC. CLBKGROUND], 28; цвет окна

MOV DWORD PTR [WC. CLMENNAME], 0

MOV DWORD PTR [WC. CLNAME], OFFSET CLASSNAME

PUSH OFFSET WC

CALL RegisterClassA@4; Регистрирует класс, определенный конструктором, с дополнительным базовым типом и типом интерфейса

; создать окно зарегистрированного класса

PUSH 0

PUSH [HINST]

PUSH 0

PUSH 0

PUSH 600; DY — высота окна

PUSH 1200; DX — ширина окна

PUSH 100; Y — координата левого верхнего угла

PUSH 100; X — координата левого верхнего угла

PUSH WS_OVERLAPPEDWINDOW

PUSH OFFSET TITLENAME; имя окна

PUSH OFFSET CLASSNAME; имя класса

PUSH 0

CALL CreateWindowExA@48

; проверка на ошибку

CMP EAX, 0

JZ _ERR

MOV [NEWHWND], EAX; дескриптор окна

PUSH SW_SHOWNORMAL

PUSH [NEWHWND]

CALL ShowWindow@8; показать созданное окно

; ------------------------------------------------------------

PUSH [NEWHWND]

CALL UpdateWindow@4; команда перерисовать видимую

; часть окна, сообщение WM_PAINT

; цикл обработки сообщений

MSG_LOOP:

PUSH 0

PUSH 0

PUSH 0

PUSH OFFSET MSG

CALL GetMessageA@16; получаем сообщение из очереди

CMP EAX, 0; если в очередь пришел ноль, значит выходим из программы

JE END_LOOP

PUSH OFFSET MSG

CALL TranslateMessage@4

PUSH OFFSET MSG

CALL DispatchMessageA@4

JMP MSG_LOOP

END_LOOP:

; выход из программы (закрыть процесс)

PUSH [MSG. MSWPARAM]

CALL ExitProcess@4

_ERR:

JMP END_LOOP

; ----------- функция определения длины строки ------------------------

; длина строки

; [EBP+08H] - указатель на строку

LENSTR PROC

PUSH EBP

MOV EBP, ESP

PUSH ESI

MOV ESI, DWORD PTR [EBP+8]

XOR EBX, EBX

LBL1:

CMP BYTE PTR [ESI], 0

JZ LBL2

INC EBX

INC ESI

JMP LBL1

LBL2:

POP ESI

POP EBP

RET 4

LENSTR ENDP

; процедура окна

; расположение параметров в стеке

; [EBP+014Н]; LPARAM

; [EBP+10H]; WAPARAM

; [EBP+0CH]; MES

; [EBP+8]; HWND

WNDPROC PROC

PUSH EBP

MOV EBP, ESP

; PUSH EBX

; PUSH ESI

; PUSH EDI

IRP REG, < EBX, ESI, EDI>; макроповторение IRP

PUSH REG

ENDM

CMP DWORD PTR [EBP+0CH], WM_DESTROY

JE WMDESTROY

CMP DWORD PTR [EBP+0CH], WM_CREATE

JE WMCREATE

CMP DWORD PTR [EBP+0CH], WM_PAINT

JE WMPAINT

CMP DWORD PTR [EBP+0CH], WM_COMMAND

JE WMCOMMND

JMP DEFWNDPROC

WMCOMMND:

MOV EAX, HWNDBTN

CMP DWORD PTR [EBP+14H], EAX; определяем нажата ли кнопка «Событие 1»

JNE BUTT1

; получить отредактированную строку

PUSH OFFSET TEXT

PUSH 150

PUSH WM_GETTEXT

PUSH HWNDEDT

CALL SendMessageA@16; показать эту строку

; записать отредактированную строку текстовое поле HWNDEDT1

PUSH OFFSET TEXT

PUSH 0

PUSH WM_SETTEXT

PUSH HWNDEDT1

CALL SendMessageA@16

JMP NODESTROY

BUTT1:

MOV EAX, HWNDBTN1

CMP DWORD PTR [EBP+14H], EAX; определяем нажата ли кнопка «Событие 2»

JNE NODESTROY

PUSH [NEWHWND]

PUSH 0

PUSH 0

CALL InvalidateRect@12; принудительная перерисовка окна

. IF TMP==0; изменение условий перерисовки окна

MOV TMP, 1

. ELSE

MOV TMP, 0

. ENDIF

JMP NODESTROY

NODESTROY:

MOV EAX, 0

JMP FINISH

WMPAINT:

PUSH OFFSET PNT

PUSH DWORD PTR [EBP+08H]

CALL BeginPaint@8

PUSH EAX; сохранить контекст (дескриптор)

; ---------------- цвет фона = цвет окна

PUSH RGBW

PUSH EAX

CALL SetBkColor@8

; ---------------- контекст

POP EAX

PUSH EAX

; ---------------- цвет текста

PUSH RGBT

PUSH EAX

CALL SetTextColor@8

POP EAX

. IF TMP==1; проверка условия прорисовки текста по событию 2

REPT 20; макроповторение REPT

PUSH EAX

; ---------------- вывести текст

PUSH OFFSET TEXT

CALL LENSTR; вызов процедуры определения длины сообщения

PUSH EBX; длина строки

PUSH OFFSET TEXT; адрес строки

ADD YT, 20

PUSH YT; Y

PUSH XT; X

PUSH EAX; контекст окна

CALL TextOutA@20

POP EAX

ENDM

. ENDIF

MOV YT, 90

PUSH OFFSET PNT

PUSH DWORD PTR [EBP+08H]

CALL EndPaint@8

MOV EAX, 0

JMP FINISH

WMCREATE:

; создать окно-кнопку «Событие1»

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20; DY

PUSH 300; DX

PUSH 10; Y

PUSH 10; X

PUSH STYLBTN

PUSH OFFSET CPBUT; имя окна

PUSH OFFSET CLSBUTN; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDBTN, EAX; запомнить дескриптор кнопки

; создать окно-кнопку «Событие2»

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20; DY

PUSH 300; DX

PUSH 85; Y

PUSH 10; X

PUSH STYLBTN

PUSH OFFSET CPBUT1; имя окна

PUSH OFFSET CLSBUTN; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDBTN1, EAX; запомнить дескриптор кнопки

; создать окно редактирования1

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20; DY

PUSH 300; DX

PUSH 40; Y

PUSH 10; X

PUSH STYLEDT

PUSH OFFSET CPEDT; имя окна

PUSH OFFSET CLSEDIT; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDEDT, EAX

; создать окно редактирования 2

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20; DY

PUSH 300; DX

PUSH 60; Y

PUSH 10; X

PUSH STYLEDT

PUSH OFFSET CPEDT; имя окна

PUSH OFFSET CLSEDIT; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDEDT1, EAX

; --------- поместить строку в окно редактирования

PUSH OFFSET TEXT

PUSH 0

PUSH WM_SETTEXT

PUSH HWNDEDT

CALL SendMessageA@16

; --------- установить фокус на окне редактирования

PUSH HWNDEDT

CALL SetFocus@4

; ------------------------------------------------------------

MOV EAX, 0

JMP FINISH

DEFWNDPROC:

PUSH DWORD PTR [EBP+14H]

PUSH DWORD PTR [EBP+10H]

PUSH DWORD PTR [EBP+0CH]

PUSH DWORD PTR [EBP+08H]

CALL DefWindowProcA@16; вызывается оконной процедурой по умолчанию,

; чтобы обеспечить обработку по умолчанию любого сообщения окна,

; которые приложение не обрабатывает

JMP FINISH

WMDESTROY:

PUSH 0

CALL PostQuitMessage@4; сообщение WM_QUIT

MOV EAX, 0

FINISH:

POP EDI

POP ESI

POP EBX

POP EBP

RET 16

WNDPROC ENDP

_TEXT ENDS

END START

5.2 Результат работы программы

6. Вывод

В ходе выполнения курсовой работы самостоятельно были изучены основы программирования на 32-битном ассемблере. Изучены макросредства. Составлена программа на языке ассемблера для 32 разрядных микропроцессоров семейства Intel, демонстрирующая применение макросредств в ассемблере.

ПоказатьСвернуть
Заполнить форму текущей работой