Статьи по Assembler


Лептонный стиль программирования - часть 9


invoke SendMessageA,hWnd,Msg,wParam,lParam

(см. также статью Вызов функций API)

В каждом модуле объявлялась как PUBLIC одна-единственная процедура, названная нами диспетчером. Упрощенно система работала так:

  • если в каком-то месте программы требовалось обратиться к лептонному сервису, вызывалась функция API SendMessage (реже, при необходимости - PostMessage), при этом в качестве окна-получателя (hWnd) указывался супервизор. Сообщение (Msg) определяло смысл запроса, а два параметра (wParam и lParam) - его параметры;
  • оконная процедура супервизора, получив это сообщение, поочередно транслировала его всем доступным в приложении диспетчерам модулей, передавая им параметры, например, через стек;
  • очередной диспетчер модуля, получив вызов от супервизора, определял, обрабатывается ли он этим модулем. Если не обрабатывается, то модуль возвращал управление супервизору с признаком "не обработано". Если обрабатывается, то передавал его на обработку и, по ее завершении, возвращал ответ в регистре eax с признаком "обработано";
  • супервизор, получив от какого-нибудь очередного модуля ответ с признаком "обработано", прекращал опрос модулей и завершал оконную процедуру, возвращая ответ в регистре eax;
  • запрашивавший модуль считывал ответ из регистра eax.

Как параметры (wParam и lParam), так и ответ (eax) могли представлять собой непосредственные данные, если они помещались в размер двойного слова, либо являться адресами (указателями) блоков памяти (структур, строк), в которые модуль-клиент и/или модуль-сервер помещали соответствующие данные. В каждом конкретном случае это определялось смыслом запроса, то есть значением сообщения (Msg).

У этой схемы, при ее общей очевидной работоспособности, имелись несколько неприятных недостатков (мы настаиваем на этом определении, ибо всякий поживший на свете человек знает, что некоторые недостатки иногда бывают очень даже приятны):

  • для своих внутренних утилитарных целей мы задействуем весь монструозный механизм сообщений Windows. (Васин элементарный запрос MASHA_GOTO_POGULYAT_NA_CHERDAK, не сомневайтесь, будет в подробностях обсосан и переварен всем двором и уж точно не минует машиного батяню-шоферюгу с вот такенными кулачищами.) Конечно, душа настоящего ассемблерщика станет невыносимо страдать при каждом таком запросе. А вы представляете, если запросы попрут, допустим, по сто штук в секунду? Прямая дорога либо к инфаркту миокарда, либо к циррозу печени;
  • очередь оконных сообщений начинает жить только после создания окна супервизора, когда заработает цикл GetMessage-TranslateMessage-DispatchMessage. А между тем, очень часто до того хочется провести некоторое количество операций по инициализации приложения. И очень хочется выполнить их тоже в лептонном стиле. Почему бы и нет?
  • два входных параметра - это, конечно, больше, чем ни одного, но заметно меньше, чем три или более. То есть маловато будет в весьма многих случаях. А ничего не поделаешь: таков формат системного сообщения Windows. Можно, конечно, дополнительно использовать регистры esi и edi, которые, как известно, сохраняются функциями API, но это откровенный паллиатив;
  • параметры передаются через стек, и поэтому их всегда два. Даже если не нужно ни одного. Налицо преступное разбазаривание кода, стека и процессорного времени;
  • 48128 сообщений, зарезервированных в диапазонах WM_USER и WM_APP - это не так уж много, неправда ли? Всего каких-нибудь 20 лет работы над программой, и вы их исчерпаете. Что будете делать тогда? Куда лучше было бы иметь в запасе 232 сообщений. Тогда можно было бы более-менее спокойно работать чуть более 1784810 лет, что в большинстве случаев следует признать достаточным.

 

Поэтому мы не станем рассматривать здесь вариант реализации лептонного стиля на базе системы сообщений Windows, а сразу перейдем к более прогрессивному - автономному варианту. Его отличительной особенностью является применимость не только под Windows, а в любой ассемблерной программе, в том числе под DOS, Linux и пр. Если он вам понравится, вы можете использовать приведенный здесь код один к одному. Он вполне работоспособен и достаточно функционален. Но еще правильнее воспринимать его как набор идей, которые вы свободно можете развить и дополнить так, как посчитаете нужным. Или, например, перевести на другой язык программирования.

Реализация и заключительные замечания - во второй части статьи.






Начало  Назад  Вперед



Книжный магазин