fillscr: PushReg <es,di,dx, ex, Cur win,eax>; сохранение в стеке
mov Cur win, 0 очистка переменной Cur win
call SetWin установка нулевого окна
mov es, Vbuff es <= значение видеосегмента
xor di, di 0 — исходный адрес видеопамяти
mov ax, Versize ах <= количество строк (Versize)
mul Horsize dx:ax = Versize Horsize
mov ex, dx ex = количество полных окон
mov dx, ax dx = размер последнего окна
pop eax восстановление содержимого еах
; Цикл записи в полностью заполняемые окна
:l_lp: push ex сохранение счетчика сегментов
mov ex, 16384 количество повторов для rep
rep stosd запись в полное окно
call NxtWin установка следующего окна
Первые пять команд примера 3.3 выполняют вспомогательные действия, а именно, сохранение в стеке тех величин, которые будут испорчены при выполнении подпрограммы, установку нулевого окна видеопамяти, запись в регистр es кода видеосегмента и очистку регистра di. В основной части подпрограммы полностью и частично заполненные окна обрабатываются по-разному. Поэтому надо предварительно вычислить количество полных окон, содержащихся в рабочей области памяти, и количество байтов в частично заполненном окне, если оно есть. В примере 3.3 эти величины вычисляются путем умножения значений переменных versize и Horsize.
Один из сомножителей команды умножения должен находиться в регистре ах, а второй указывается в самой команде. Старшая часть результата умножения находится в регистре dx, а младшая — в ах. Таким образом, произведение равно 65 536 [dx] + [ах], квадратные скобки обозначают содержимое указанных в них регистров. Другими словами, после умножения в регистре dx находится количество полных окон, а в регистре ах — количество байтов в частично заполненном окне.
После умножения содержимое регистра dx копируется в сх, содержимое регистра ах — в dx и восстанавливается из стека испорченное при умножении содержимое регистра еах (код цвета точек). Далее действия выполняются в следующем порядке: сначала окрашиваются точки полностью заполненных окон, а затем точки частично заполненного окна, если такое есть.
Окрашивание точек полностью заполненных окон происходит в цикле, имеющем метку fi_ip, он повторяется столько раз, сколько полных окон содержит рабочая область экрана. Заполнение окна выполняет микропрограммный цикл rep stosd, для его ускорения строковая операция (stosd) записывает в видеопамять сразу четыре байта. Поэтому предварительно в регистре сх задается 16 384 повтора этой операции. После закрашивания всего сегмента происходит обращение к подпрограмме Nxtwin для установки следующего окна. Затем из стека восстанавливается содержимое регистра сх и команда loop управляет повторами никла.
После выхода из цикла f i_ip в регистр сх копируется из dx оставшееся количество байтов и выполняется микропрограммный цикл rep stosb.
Замечание 1
Замечание 1
Если в регистре сх находится 0, то строковая операция не будет выполняться ни разу (см. раздел).
Заключительные действия выполняет фрагмент, имеющий метку fi_oui В нем восстанавливаются сохраненные в стеке величины, исходное окно видеопамяти и происходит возврат из подпрограммы.
Приведенный пример иллюстрирует простейший случай работы с окнами видеопамяти, когда не требуется специальная проверка достижения границы сегмента и необходимости переключения окна. В большинстве случаев такая проверка нужна и на ее выполнения затрачиваются дополнительные действия, замедляющие процесс построения изображения на экране. Исключить такие действия невозможно, но можно попытаться свести их к необходимому минимуму, в зависимости от конкретного алгоритма построения изображения. Мы будем неоднократно возвращаться к этому вопросу при описании приводимых в книге примеров.