Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





В том виде, в котором он представлен, цикл обработки сообщений слишком сложен, поэтому первое, что мы сделаем, — упростим его. Мы не используем в нашем приложении "быстрые" клавиши (акселераторы), поэтому обработчик сообщений для таких клавиш будет отсутствовать. Соответственно, не нужно проверять условие:
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
Уберем этот условный оператор, и фрагмент кода упростится (листинг 4.8).
Листинг 4.8. Упрощенный вариант цикла обработки сообщений
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Проанализировав упрощенный цикл обработки сообщений, не составит особых усилий написать аналогичный цикл на языке ассемблера (листинг 4.9).
Листинг 4.9. Цикл обработки сообщений на языке ассемблера
StartLoop:
push
push
push NULL
0
0
lea EAX, msg
push ЕАХ
call GetMessage
cmp EAX, О
je ExitLoop
lea EAX, msg
push EAX
call TranslateMessage
lea EAX, msg
push EAX
call DispatchMessage
jmp StartLoop
ExitLoop:
mov - EAX, msg.wParam
ret

Наконец, представим исходный текст оконной процедуры WndProc на ассемблере. Напомню, что исходный текст оконной процедуры WndProc на С++ был приведен ранее в листинге 4.6. Не составит труда, учитывая наш предыдущий опыт, написать эквивалент оконной процедуры на ассемблере (листинг .4.10).
Листинг 4.10. Оконная процедура WndProc на языке ассемблера
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
1Param :DWORD
LOCAL hdc :HDC
LOCAL ps :PAINTSTRUCT
cmp uMsg, WM_PAINT
jne next_l
lea
push
push
EDX, ps
EDX
hWnd
call BeginPaint
mov hdc, EAX
push lenText
push offset textMes
push 100
push 100
push hdc
call TextOut
lea EDX, ps
push EDX
push hWnd
call EndPaint
ret
next 1:
cmp uMsg, WM_DESTROY
jne next 2
push NULL
call PostQui tMessage
xor EAX, EAX
ret
next 2:
push 1Param
push wParam
push uMsg
push hWin
call DefWindowProc
ret
WndProc endp

Мы проанализировали, как работает классическое Windows-приложение, написанное на С + + , и знаем, как реализовать основные функциональные блоки такой программы на ассемблере. Прежде чем представить наше первое графическое приложение на языке ассемблера, вспомним, как выглядит в общих чертах каркас такого приложения. Для разработки приложений Windows мы будем использовать макроассемблер MASM. Структура приложения на ассемблере представлена в листинге 4.11.
Листинг 4.11. Структура приложения на языке ассемблера
.386
.model flat, stdcaii
.data
<данные>
.code
метка:
<программный код>
end <метка>

Большинство выражений и директив ассемблера, которые используются в этом шаблоне, уже встречались в предыдущих главах. Кратко напомним их назначение.
В первой строке находится директива .386, которая указывает ассемблеру на то, что будет использоваться набор команд 386-го процессора. Директива .model flat указывает ассемблеру, что используется плоская модель памяти.
Как мы уже знаем из предыдущих глав, директива stdcaii указывает ассемблеру на порядок передачи параметров при вызове внешних процедур.
Параметры в процедуру передаются справа налево, причем первый параметр помещается в стек первым. Вызываемая процедура также должна восстановить стек. Директива stdcaii используется потому, что при разработке Windows-приложений на ассемблере мы в основном будем использовать WIN API, а почти все функции (за исключением wsprintf) этого интерфейса передают параметры в соответствии с этой директивой. К примеру, если мы используем функцию WIN API с условным названием myfunc с четырьмя параметрами paraml, param2, рагатЗ, рагат4, определенную как
my_func (paraml, рагат2, рагатЗ, param4), ТО ДЛЯ вызова ее ИЗ Программы на ассемблере необходимо выполнить следующую последовательность команд:
push param4
push рагатЗ
push param2
push paraml
call my_func


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru