Предыдущий раздел ДИСПЕТЧЕР КОМАНД Следующий раздел

14.3. Выполнение команды

Этап “Выполнение команды” реализуется путем вызова процедуры Command. Данная процедура получает в регистре DL код ASCII, соответствующий команде, и в зависимости от этого кода вызывает процедуру, выполняющую заданное командой действие.

На рис.48 приведена блок-схема процедуры Command. Центральной особенностью ее алгоритма является использование таблицы переходов. В данной таблице для каждой разрешенной команды пользователя отводятся три байта. В первом байте находится скан-код, соответствующий команде, а в двух других байтах – начальный адрес (внутрисегментное смещение) соответствующей процедуры. В последнем байте таблицы находится 0ffh.

Процедура Command совместно с главной процедурой Dispatcher обеспечивают выполнение алгоритма диспетчера команд. Поэтому обе процедуры, а также таблицу переходов Table мы поместим в один и тот же файл Dispatch.asm. Заключительный фрагмент этого файла содержит модули Command и Table:

org  100h

;           Координирует выполнение модулей редактора

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

;

Dispatcher:

     .     .     .     .     .     .     .     .                      ; Тело главной процедуры

int     20h

;

;              Интерпретатор команд

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

;     Входы:   DL – скан-код, соответствующий команде

;    Чтение:  Table – таблица переходов

;

Command:

push  bx

mov   bx,Table                       ; ВХßадрес таблицы

.M1:                      cmp            byte[bx], 0ffh      ; Конец таблицы ?

je       .Exit                           ; Да, кода  нет в таблице    

cmp   dl,[bx]                        ; Это вход в таблицу?

add   bx,3                            ; Нет, переход к

clc                                       ;    следующему

jmp    .M2                            ;     элементу таблицы

.Dispatch:             inc     bx                              ; Адрес процедуры

call    [bx]                           ; Вызов процедуры

.Exit:                     stc                                      ;   CF  ß  1

.M2:                      jnc     .M1                           ;Повторение для нового элемента таблицы

pop   bx        

ret

;   Таблица содержит скан-коды управляющих клавиш и адреса процедур,

;  выполняющих соответствующие команды

Table                     db     3bh                              ; <F1>

dw    Init_sector

db    3ch                               ; <F2>        

dw    Write_sector

db    3dh                               ; <F3>

dw   Next_sector

db     3fh                               ; <F5>

dw     Prev_sector

db     40h                              ; <F6>

dw     N_sector

db     0ffh                              ; Конец таблицы

 

 

DL – код команды

CF – признак завершения (0 – продолжить, 1 – завершить работу)

 

Рис. 48.  Алгоритм  процедуры  Command

 

Рассмотрим особенности этих модулей. Во-первых, сравним между собой два оператора: “cmp byte [bx], 0” и “cmp dl, [bx]”. Оба этих оператора выполняют сравнение заданной величины (число 0 или содержимое регистра dl) с содержимым той ячейки памяти, адрес которой находится в регистре bx.  В данном регистре находится адрес-смещение младшего байта ячейки памяти, но не задана длина этой ячейки. Об этой длине транслятор может узнать или из анализа второго операнда команды, или если задан дополнительный псевдооператор byte, wordили dword. В первой из двух записанных выше команд псевдооператор byte сообщает транслятору, что сравниваются байты. Аналогично, команда “cmp word [bx], 0” будет сравнивать слова. Во второй из приведенных выше команд дополнительный псевдооператор излишен, так как о байтовой длине ячейки памяти сообщает другой операнд команды – регистр dl.

Для того чтобы получить адреса процедур, вызываемых диспетчером и содержащихся в таблице, мы записали имя каждой процедуры в качестве операнда псевдооператора dw, выполняющего запрос к транслятору с просьбой выполнить резервирование слова памяти и поместить в это слово требуемое значение. В данном случае таким требуемым значением является адрес-смещение первого байта процедуры. Транслятор выполнит нашу просьбу правильно, так как имя процедуры записано без квадратных скобок, что и означает ее адрес.

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

 


Предыдущий раздел В начало Следующий раздел