Работа с прямоугольными областями
Подпрограмма Savereg
В примере 7.15 показано, как можно переставить адреса операндов на время выполнения цикла пересылки, а затем восстановить их исходное расположение в регистрах. Входные параметры в данном случае задаются так же, как для примера 7.14.
Пример 7.15. Подпрограмма пересылки из видеопамяти в оперативную.
Savereg: PushReg <bx, ex, di, si, es, Cur_win>; сохранение в стеке mov bx, fs; копируем код сегмента из fs в bx mov es, bx; копируем код сегмента из bx в es mov fs, Vbuff; fs = сегмент видеобуфера ЮЗак П78 xchg di, si перестановка адресов di и si call calloffs вычисление константы offsline svrg: push ex сохранение значения счетчика строк mov ex, dx задание количества точек в строке call saveline копируем очередную строку add si, bx адрес начала следующей строки jnc @F › адрес в пределах окна call Nxtwin установка следующего окна @@: pop ex восстановление счетчика строк loop svrg управление повторами цикла push es помещаем код сегмента из es в стек pop fs и выталкиваем его из стека в fs PopReg <Cur_win, es, si, di, ex, bx>; восстановление из стека call setwin восстановление исходного окна ret возврат из подпрограммы
Напомним, что команда xchg не работает с сегментными регистрами, а у команды mov только один операнд может быть именем сегментного регистра. Поэтому для пересылки содержимого одного сегментного регистра в другой приходится использовать либо регистр-посредник, либо стек. Оба этих способа показаны в примере 7.15.
Основной цикл пересылки примера 7.15 имеет имя svrg, он отличается от аналогичного цикла примера 7.14 (mvsr) только одной командой. При вычислении адреса следующей строки константа коррекции прибавляется к содержимому регистра si, а не di, как это делалось в примере 7.14.
Заливка прямоугольной области
Изменим текст примера 7.14 так, чтобы его можно было использовать для окрашивания прямоугольной области заданным цветом. В этом случае при выполнении цикла должна вызываться подпрограмма horline, а не drawline. Регистр si не используется, поэтому его имя исключается из списков PushReg и PopReg.
Измененный текст подпрограммы показан в примере 7.16. При ее вызове код цвета указывается в регистрах ах или еах (в зависимости от видеорежима). Ширина прямоугольной области задается в регистре dx, а высота – в сх. Адрес видеопамяти для левого верхнего угла должен находиться в регистре di, регистры fs:si не используются. Предполагается, что es содержит код видеосегмента и установлено исходное окно видеопамяти.
Пример 7.16. Окрашивание прямоугольной области заданным цветом.
Fillreg: PushReg <bx, ex, di, Cur_win>; сохранение в стеке call calloffs; вычисление константы offsline fillrg: push ex; сохранение значения счетчика строк mov ex, dx; задание количества точек в строке call horline рисуем очередную строку add di, bx адрес начала следующей строки jnc @F › адрес в пределах окна call Nxtwin установка следующего окна @@: pop ex восстановление счетчика строк loop fillrg управление повторами цикла PopReg <Cur_win, di, ex, bx>; восстановление из стека jmp setwin установка окна и выход
В отличие от примеров 7.14 и 7.15, в данном случае размер закрашиваемой области экрана не ограничен, лишь бы хватило памяти, установленной на видеокарте. Например, для окрашивания всей рабочей поверхности экрана в нужный цвет, перед вызовом подпрограммы код цвета помещается в регистре bx (или еах), в сх копируется переменная versize, а в dx – Horsize, регистр di очищается и устанавливается нулевое окно видеопамяти.
Текст примера 7.16 не зависит от видеорежима, но в нем вызывается подпрограмма horline, в тексте которой есть переменные команды, зависящие от видеорежима. Поэтому, в отличие от подпрограмм пересылки, подпрограмма Filireg не является универсальной.
Многофункциональная подпрограмма
Основное различие текстов примеров 7.14 и 7.16 заключается в имени вспомогательной подпрограммы, используемой для выполнения конкретных действий.
Для того чтобы приведенная в примере 7.14 подпрограмма стала многофункциональной, команду call drawiine надо заменить командой call bp, a перед вызовом указывать в регистре bр адрес вспомогательной подпрограммы. Аналогичный прием описан ранее, на примере подпрограммы draw. Там же показано, как формируется адрес в регистре bр.
После указанного изменения подпрограмму Rstreg можно использовать, например, для построения рисунков, изменения их цвета, окрашивания прямоугольной области и любых других действий, которые способны выполнять вызываемые вспомогательные подпрограммы.