Графические устройства

         

Рисование горизонтальной линии справа налево



Пример 3.7. Рисование горизонтальной линии справа налево

; Вариант 1, используется команда пересылки. invline:mov es:[di], al запись кода точки в видеобуфер sub di, 01 уменьшение адреса на 1
jnc @F переход, если нет переноса
call PrevWin установка предыдущего окна
@@: loop invline управление повторами цикла
возврат из подпрограммы

Вариант 2, используется строковая операция. установка флага направления запись кода точки в видеобуфер начало нового сегмента ? -> нет
установка предыдущего окна управление повторами цикла очистка флага направления возврат из подпрограммы
invline: std
invlp: stosb
cmp di, -1 jne @F call PrevWin
@@: loop invlp
eld ret

В примере 3.7 после записи в видеопамять содержимое регистра di уменьшается на 1, поэтому каждая следующая точка располагается на экране слева от предыдущей. Если при очередном уменьшении адреса будет пройдена нижняя граница сегмента, то надо установить предыдущее окно видеопамяти. Нижней границей текущего сегмента является нулевой адрес. При его уменьшении на 1 получается отрицательный результат, имеющий код OFFFFh, который является старшим адресом предыдущего сегмента.

Контроль текущего адреса выполняется по-разному. В первом варианте для этого проверяется состояние С-разряда регистра флагов после операции вычитания. При вычитании единицы из нуля он будет установлен, что приведет к вызову подпрограммы Prevwin. Во втором варианте вычитание выполняет строковая операция, не вырабатывающая признаки, поэтому проверяется код результата и если он равен ' — 1", то вызывается подпрограмма FrevWin.

Важно
В первом варианте примера 3.7 вместо команды sub di, 01 нельзя использовать dec di, поскольку последняя не вырабатывает признак переноса.

Подпрограммы примера 3.6 достаточно просты, но это не самый быстрый способ рисования горизонтальной линии. Если не происходит смена окна, то при записи кода каждой точки выполняются четыре команды. В первом варианте одна из них (jne @F), а во втором две (or di, di и jne @F) производят проверку текущих значений адреса.
Вероятность того, что при рисовании горизонтальной линии значение адреса выйдет за границу сегмента не превышает 1%. Например, при работе в режиме ioih точки только 4 из 480 строк расположены в двух окнах. Следовательно, примерно в 99% случаев проверка текущего адреса в процессе рисования не нужна, и выполняющие ее команды можно исключить из тела цикла записи точек. Сказанное не означает, что проверка не нужна вообще, просто она должна выполняться перед циклом рисования, а не в самом цикле.



Содержание раздела