Статьи по Assembler


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


 

Файл модуля XX_*.asm:

;------------------------- include-файлы include @struct.inc include windows.inc include globals.inc ;... .code ;... ;------------------------- диспетчер @dispatcher PROC USES ebx ecx edx esi edi pray mov eax,pray ;....................... обработка бродкастов @if(eax==B_START) ;... @elseif(eax==B_STOP) ;... ;....................... обработка молитв @elseif(eax==P_GET_STRING) mov buffer_address,@par0 ;пример использования параметров молитвы mov buffer_size,@par1 mov id,@par2 ;... jmp ok ;....................... завершение диспетчера @endif nok: ;не обработано xor eax,eax ok: ;обработано ret @dispatcher ENDP

Пояснения:

  • Диспетчер - это процедура, которая содержится в каждом модуле, обрабатывающем лептонные вызовы - молитвы или бродкасты. Идея диспетчера очень проста: сравнение параметра pray со списком лептонных вызовов, обрабатываемых данным модулем. Если полученный лептонный вызов обрабатывается, то после его обработки диспетчер возвращает управление супервизору с ненулевым (полученным в результате обработки) значением в регистре eax (выполняется выход на метку ok:). В противном случае регистр eax сбрасывается в 0 (выполняется выход на метку nok:). Что касается бродкастов, то все равно, на какую метку передается управление по завершении их обработки.
  • Имя диспетчера, поскольку оно глобально в пределах исполняемого модуля, должно быть уникальным. А диспетчеров у нас - по одному на каждый модуль. Во избежание конфликтов здесь применен следующий прием. Имя @dispatcher на самом деле является вызовом макроса, описанного в файле @struct.inc (см.выше). Этот макрос формирует действительное имя процедуры вида dispatcher_XX, где XX - идентификатор модуля.
  • Входными значениями для диспетчера являются передаваемый через стек идентификатор лептонного вызова (pray) и до четырех параметров, передаваемых через регистры: @par0 (он же регистр esi), @par1 (edi), @par2 (edx), @par3 (ecx). Эквиваленты параметров определены в файле @struct.inc.
  • Использовать в качестве параметров действительные имена регистров или их эквиваленты - зависит от предпочтений программиста. Применение эквивалентов, освобождая программиста от необходимости помнить то, в каком регистре передается какой параметр, одновременно может явиться источником тяжелых ошибок, если программист вздумает вдруг воспользоваться эквивалентами регистров в качестве входных параметров диспетчера после того, как что-нибудь с этими регистрами уже поделает.
  • Можно придумать много различных вариантов организации диспетчера, оптимизирующих как использование памяти, так и время выполнения (если это имеет смысл). Здесь показан простейший вариант, основанный на применении директив @if-@elseif-@endif.
  • Показанное здесь разбиение процедуры диспетчера на части (обработка бродкастов и обработка молитв) условно. На самом деле очередность выполнения сравнений, конечно же, смысла не имеет.
  • Диспетчер, также как и супервизор, сохраняет значения всех регистров, за исключением регистра eax. Это помогает уберечься от труднообнаруживаемых ошибок, связанных со случайным изменением содержимого регистров в процессе опроса диспетчеров.




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



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