• Сервис онлайн-записи на собственном Telegram-боте
    Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое расписание, но и напоминать клиентам о визитах тоже. Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.
    Для новых пользователей первый месяц бесплатно.
    Чат-бот для мастеров и специалистов, который упрощает ведение записей:
    Сам записывает клиентов и напоминает им о визите;
    Персонализирует скидки, чаевые, кэшбэк и предоплаты;
    Увеличивает доходимость и помогает больше зарабатывать;
    Начать пользоваться сервисом
  • Как продвинуть сайт на первые места?
    Вы создали или только планируете создать свой сайт, но не знаете, как продвигать? Продвижение сайта – это не просто процесс, а целый комплекс мероприятий, направленных на увеличение его посещаемости и повышение его позиций в поисковых системах.
    Ускорение продвижения
    Если вам трудно попасть на первые места в поиске самостоятельно, попробуйте технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Если ни один запрос у вас не продвинется в Топ10 за месяц, то в SeoHammer за бустер вернут деньги.
    Начать продвижение сайта


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

Построение рисунков, использующих палитру. Построение рисунка сверху вниз.

Подпрограмма Smlbmp

Текст подпрограммы, выполняющей построение небольшого рисунка формата BMP описанным способом, приведен в примере А.9. Перед ее вызовом адрес левого верхнего угла рисунка в видеопамяти помещается в регистр di и устанавливается окно, которому принадлежит этот адрес. Регистр es должен содержать код видеосегмента. В регистре si указывается размер образа рисунка в байтах.

Пример А.9. Построение рисунка формата ВМР сверху вниз.

Smlbmp: pusha сохранение "всех" регистров
PushReg <fs,gs,Cur wi n>; сохранение fs, gs, Cur win
mov ax, horsize ax = horsize
sub ax, iwidth ax = horsize – iwidth
mul bytppnt ax = (horsize – iwidth) * bytppnt, dx = 0
mov dx, ax dx = ax, для коррекции адреса строки
mov ex, si ex = si, размер образа рисунка
mov SwpOffs, 0 начало считываемых данных
call readf чтение образа рисунка
jnc ok › чтение без ошибок
; Здесь должны выполняться действия в случае ошибки при чтении
ok: mov fs, SwpSeg fs = сегмент буфера обмена
mov gs, GenSeg!! gs = сегмент таблицы цветов
mov ex, iheight сх = количество строк в рисунке
invout: push ex сохраняем счетчик повторов
mov ex, iwidth сх = размер строки рисунка
sub si, fwidth адрес начала новой строки
call drawline!! или call bx – построение строки
pop ex восстанавливаем счетчик повторов
add si, rmndr учитываем "лишние байты"
sub si, fwidth адрес начала построенной строки
add di, dx коррекция адреса видеопамяти
jne @F › адрес в пределах сегмента
call NxtWin установка следующего окна
@@: loop invout; управление повторами цикла
PopReg <Cur win,gs,fs>; восстановление Cur win, gs, fs
popa; восстановление "всех" регистров
call setwin; восстановление исходного окна
ret; возврат из подпрограммы

Выполнение примера А.9 начинается с сохранения в стеке содержимого регистров общего назначения, сегментных регистров fs, gs и переменной cur_win. Следующие четыре команды вычисляют константу для коррекции адресов строк видеопамяти по способу, описанному в примере 7.13.

Для чтения образа файла в регистр сх помещается его размер, очищается переменная Swpoffs и происходит обращение к подпрограмме readf. Если чтение прошло без ошибок, то команда jnc ok обойдет строку, состоящую только из комментария. Что делать при ошибках чтения, решать вам.

В подпрограммах построения строк (drawiine) регистр fs используется при чтении кодов точек из оперативной памяти, а регистр gs – при работе с таблицей цветов. Поэтому перед началом основного цикла в них записываются коды соответствующих сегментов.

Цикл построения рисунка имеет метку invout. Работа с адресами в нем организована так, что при каждом повторе регистр di содержит адрес очередной строки видеопамяти, а регистр si – адрес последней обработанной строки образа рисунка (при первом входе это размер рисунка в байтах).

Перед вызовом подпрограммы drawiine содержимое si уменьшается на размер строки в файле (fwidth) и указывает начало очередной строки. При выполнении подпрограммы drawiine регистр si увеличится на iwidth. Поэтому после возврата из drawiine значение si увеличивается на rmndr (количество лишних байтов) и уменьшается на fwidth. В результате регистр si будет содержать адрес начала последней обработанной строки.

Адрес начала следующей строки видеопамяти, как обычно, увеличивается на константу переадресации, которая хранится в регистре dx. Если при сложении (add di, dx) происходит переполнение, то устанавливается следующее окно видеопамяти.

Команда loop invout повторяет выполнение цикла нужное количество раз, после чего восстанавливаются сохраненные в стеке величины, исходное окно видеопамяти и происходит возврат на вызывающий модуль.

По сравнению с обычным циклом построения рисунка (см. пример 7.23) в данном случае добавились три команды, корректирующие значение регистра si. При желании их количество можно сократить до двух. Подумайте, как это сделать, но не забывайте, что fwidth – rmndr не обязательно равно iwidth. Вспомните, как вычислялись эти величины.

Замечание
Напомним, что имя подпрограммы построения строки не обязательно указывать в явном виде. Команду call drawline можно изменить на call bx, а перед обращением формировать в регистре bх адрес подпрограммы построения строки (см. раздел в данном приложении)
.

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