Иллюстрированный самоучитель по SVGA

Построение геометрических фигур. Прямые линии.

Линия может размещаться в текущем окне полностью или частично. Для проверки этого в примере 3.8 текущий адрес копируется в регистр dx и к нему прибавляется размер линии. Если при этом не произошло переполнение, то линия полностью помещается в текущем окне и регистр dx надо очистить. Если при сложении произошло переполнение, то команда jc @F исключает очистку регистра dx, поскольку в нем находится количество точек остатка, который будет нарисован после смены окна. Команда sub ex, dx вычитает остаток (или 0) из общего числа точек и таким способом определяет количество повторов первого микропрограммного цикла. Следующая команда rep stosb рисует часть линии, расположенную в исходном окне видеопамяти.

Затем проверяется текущий адрес видеопамяти и если он отличен от нуля, то линия нарисована полностью и происходит выход из подпрограммы. Если же текущий адрес равен нулю, то устанавливается следующее окно видеопамяти, в регистр сх копируется содержимое регистра dx и выполняется команда rep stosb, рисующая остаток прямой. После этого происходит выход из подпрограммы. Поскольку подпрограмма работает с регистром dx, то его исходное содержимое сохраняется в стеке и восстанавливается при выходе.

Уважаемые читатели, попробуйте ответить на вопрос – почему в примере 3.8 перед установкой окна проверяется текущий адрес видеопамяти (or di, di), а не размер остатка строки (содержимое регистра dx)?

Давайте посчитаем, чего мы добились. Если прямая содержит N точек и полностью помещается в текущем окне, то при ее построении по подпрограммам примера 3.6 будет выполнено 4N команд, а при построении по подпрограмме 3.8 всего 10 команд (не считая ret). Одной из них является команда rep stosb, которая записывает N байтов в видеопамять. От нее зависит время, затрачиваемое на рисование линии. Можно считать, что мы сократили это время, по крайней мере, в 4 раза по сравнению с примером 3.6 и это вполне оправдывает увеличение размера подпрограммы примера 3.8.

Дополнительные возможности ускорения

Для дальнейшего ускорения процесса рисования в микропрограммном цикле нужно записывать коды сразу двух или четырех точек.

Для записи точек парами вместо команды rep stosb надо использовать команду rep stosw, предварительно уменьшив содержимое регистра сх в два раза путем сдвига на 1 разряд вправо. Если в регистре сх находится нечетное число, то при таком сдвиге младшая единица кода попадет в С-разряд регистра флагов (признак переполнения). Следовательно, после сдвига надо проверить состояние С-разряда и записать дополнительную точку, если он установлен. Таким образом, для сокращения цикла записи в два раза в примере 3.8 каждую команду rep stosb надо заменить следующей группой команд (см. пример 3.9).

Пример 3.9. Замена команды rep stosb на rep stosw.

shr ex, 01; уменьшаем количество точек в два раза
jnc @F; › обход следующей команды (stosb)
stosb; запись дополнительной точки
@@: rep stosw; основной цикл записи по два байта

Для записи кодов четырех точек при каждом обращении к видеопамяти нужно использовать команду rep stosd, предварительно уменьшив содержимое регистра сх в четыре раза. В тех случаях, когда содержимое сх не кратно четырем, надо дополнительно рисовать 1, 2 или 3 точки. Для упрощения выполняемых действий содержимое сх изменяется в два приема. Сначала оно уменьшается в два раза, и если получен признак переноса, то рисуется одна дополнительная точка. Затем оно повторно уменьшается в два раза и если опять получен признак переноса, то рисуются две дополнительные точки. После этого можно использовать команду rep stosd. Способ выполнения этих действий показан в примере 3.10.

Пример 3.10. Замена команды rep stosb на rep stosd.

shr сx, 01 уменьшаем количество точек в два раза
jnc @F › обход следующей команды (stosb)
stosb запись дополнительной точки
@@: shr ex, 01 уменьшаем количество точек в два раза
jnc @F › обход следующей команды (stosw)
stosw запись двух дополнительных точек
@@: rep stosd основной цикл записи по четыре байта

Важно
При использовании ускоренных вариантов рисования код цвета точки надо записать в оба байта регистра ах или в четыре байта регистра еах
.

Таким образом, процесс рисования горизонтальной прямой можно дополнительно ускорить примерно в два или четыре раза, но при этом текст примера 3.8 увеличится на б или 12 команд. Поэтому в каждом конкретном случае вам придется решать, что важнее, размер подпрограммы или время рисования.

Советуем вам составить вариант примера 3.8 для ускоренного рисования горизонтальной прямой в обратном направлении. Все, что надо при этом учесть, уже описано в данной главе.

Замечание
Описанные подпрограммы рисуют одноцветные линии. Разноцветная линия – это уже рисунок. Для того чтобы ее точки (или группы точек) имели разные цвета, недостаточно простого изменения их кодов в процессе рисования. Должна быть подготовлена и установлена палитра цветов, соответствующих кодам точек. Обо всем этом речь пойдет в третьем разделе данной главы и в Главе4
.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.