|
|
Таблица 4.9 |
|
|
|
Код |
Размер |
Видеорежим |
01 |
40 х 25 |
черно-белый режим в цветном адаптере |
10 |
80 х 25 |
черно-белый режим в цветном адаптере |
11 |
80 х 25 |
черно-белый режим в черно-белом адаптере |
Программа, работающая с неизвестным типом монитора, может провеpить тип по регистру ax после int 11h и затем установить необходимый режим.
ah=02: Установка позиции курсора. Эта функция устанавливает курcор в любую позицию на экране в соответствии с координатами cтроки и столбца.
Номер страницы обычно равен 0, но может иметь значение от 0 до 3 при 80 столбцах на экране. Для установки позиции курсора необходимо занести в регистр ah значение 02, в регистр bh номер страницы и в регистр dx координаты строки и столбца:
mov ah,02 |
; установить положение курсора |
mov bh,00 |
; страница 0 |
mov dh,строка |
; строка |
mov dl,столбец |
; столбец |
int 10h |
; вызвать BIOS |
ah =06: Прокрутка экрана вверх. В текстовом режиме установка в регистре al значения 00 приводит к полной прокрутке вверх всего экрана, очищая его пробелами. Установка ненулевого значения в регистре al определяет количество строк прокрутки экрана вверх. Верхние строки уходят с экрана, а чистые строки вводятся снизу. Следующие команды выполняют прокрутку всего экрана на одну строку:
mov ax,0601h |
; прокрутить на одну строку вверх |
mov bh,07 |
; атрибут: нормальный, черно-белый |
mov cx,0000 |
; координаты от 00,00 |
mov dx,184Fh |
; до 24,79 (полный экран) |
int 10h |
; вызвать BIOS |
Для прокрутки любого количества строк необходимо установить соответствующее значение в регистре al. Регистр bh содержит атрибут для нормального или инвертированного отображения, мигания, установки цвета и т.д. Значения в регистрах cx и dx позволяют прокручивать любую часть экрана. Ниже объясняется стандартный подход к прокрутке:
1.Определить в элементе ROW (строка) значение 0 для установки строки положения курсора.
2.Выдать текст и продвинуть курсор на следующую строку.
3.Проверить, находится ли курсор на последней строке (cmp ROW,22).
41
4.Если да, то увеличить элемент ROW (inc ROW) и выйти.
5.Если нет, то прокрутить экран на одну строку и, используя ROW, переустановить курсор.
ah =07: Прокрутка экрана вниз. Для текстового режима прокрутка экрана вниз обозначает удаление нижних строк и вставка чистых строк сверху.
Регистр ah должен содержать 07, значения остальных регистpов аналогичны функции 06 для прокрутки вверх.
ah =08: Чтение атрибута/символа в текущей позиции курсора. Для чтения символа и байта-атрибута из дисплейного буфера, как в текстовом, так и в графическом режиме используются следующие команды:
mov ah,08 ; запрос на чтение атр./симв.
mov bh,00 ; страница 0 (для текстового режима)
int 10h ; вызвать BIOS
Данная функция возвращает в регистре al значение символа, а в ah – его атрибут. В графическом режиме функция возвращает 00h (означает, что это не ASCII-код). Так как эта функция читает только один cимвол, то для символьной строки необходима организация цикла.
ah=09: Вывод атрибута/символа в текущую позицию курсора. Для вывода на экран символов в текстовом или графическом режиме с установкой мигания, инвертирования и т.д. можно воспользоваться
следующими командами: |
|
mov ah,09 |
; функция вывода |
mov al,символ |
; выводимый символ |
mov bh,страница |
; номер страницы (текстовый режим) |
mov bl,атрибут |
; атрибут или цвет |
mov cx,повторение |
; число повторений символа |
int 10h |
; вызвать BIOS |
В регистр al должен быть помещен выводимый на экран символ. Значение в регистре cx определяет число повторений символа на экране. Вывод на экран последовательности различных символов требует организации цикла. Данная функция не перемещает курсор. В следующем примере на экран выводится пять мигающих "сердечек" в
инвертированном виде: |
|
mov ah,09 |
; функция вывода |
mov al,03h |
; черви (карточная масть) |
mov bh,00 |
; страница 0 (текст. режим) |
mov bl,0F0h |
; мигание, инверсия |
mov cx,05 |
; пять раз |
int 10h |
; вызвать BIOS |
|
42 |
Втекстовом (но не в графическом) режиме символы автоматически выводятся на экран и переходят с одной строки на другую. Для вывода на экран текста запроса или сообщения необходимо составить программу, которая устанавливает в регистре cx значение 01 и в цикле загружает в регистр al из памяти выводимые символы текста. Так как регистр cx в данном случае занят, то нельзя использовать команду loop. Кроме того, при выводе каждого символа необходимо дополнительно продвигать курсор в следующий столбец (функция 02).
Вграфическом режиме регистр bl используется для определения цвета графики. Если бит 7 равен 0, то заданный цвет заменяет текущий цвет точки; если бит 7 равен 1, то происходит комбинация цветов с помощью команды xor.
4.28. Расширенный ASCII-код
ASCII-коды от 128 до 255 (80h–FFh) представляют собой ряд специальных символов, полезных при формировании запросов, меню, специальных значков с экранными атрибутами.
4.29. Арифметические операции
Арифметические операции над целыми двоичными числами без знака рассмотрены в уч. пос., ч. 1, а над целыми двоичными числами со знаком – в уч. пос., ч. 3.
4.30. Преобразование типов для логических операций
Что делать, если размеры операндов, участвующих в логических операциях, разные? Например, предположим, что в операции ИЛИ один операнд является словом, а другой занимает двойное слово. Выше сказано, что в арифметической операции должны участвовать операнды одного формата. То же обязательно и для логических операций. Но в отличие от арифметических операций, в которых могут участвовать как числа беззнаковые, так и числа со знаком, в логических операциях операнды – беззнаковые. И выход – тот же, что и для беззнаковых операнд арифметических операций (см. уч. пос., ч. 1, подразд.4.69). В этом случае можно либо на базе исходного операнда сформировать новый (формата двойного слова), старшие разряды которого просто заполнить нулями, либо применить команду movzx, относящуюся к командам обработки строк (см. уч. пос., ч. 7).
Примечание. Нельзя применять ни команды преобразования типов cbw, cwd, cwde, cdq (см. подразд.5.15), ни команду movsx, распространяющую знак на старшие позиции.
4.31. Команды работы со стеком
43
Эта группа команд (перемещение данных в стек и из стека) представляет собой набор специализированных команд, ориентированных на организацию гибкой и эффективной работы со стеком.
Стек − это область памяти, специально выделяемая для временного хранения данных программы. Важность стека определяется тем, что для него в структуре программы предусмотрен отдельный сегмент. На тот случай, если программист забыл описать сегмент стека в своей программе, компоновщик tlink выдаст предупреждающее сообщение.
Для работы со стеком в МП 8086 предназначены три регистра:
•ss −сегментный регистр стека;
•sp − регистр указателя стека;
•bp − регистр указателя базы кадра стека.
Размер стека зависит от режима работы микропроцессора и ограничивается 64 Кб (или 4 Гб в защищенном режиме).
В каждый момент времени доступен только один стек, адрес сегмента которого содержится в регистре ss. Этот стек называется текущим. Для того чтобы обратиться к другому стеку (“переключить стек”), необходимо загрузить в регистр ss другой адрес. Регистр ss автоматически используется процессором для выполнения всех команд, работающих со стеком.
Перечислим еще некоторые особенности работы со стеком:
•запись и чтение данных в стеке осуществляется в соответствии с принципом lifo (Last In First Out − “последним пришел, первым ушел”);
•по мере записи данных в стек последний растет в сторону младших адресов. Эта особенность заложена в алгоритм команд работы со стеком;
•при использовании регистров sp и bp для адресации памяти ассемблер автоматически считает, что содержащиеся в нем значения представляют собой смещения относительно сегментного регистра ss.
В общем случае стек организован так, как показано на рис. 4.1.
Для работы со стеком предназначены регистры ss, sp и bp. Эти регистры используются комплексно, и каждый из них имеет свое функциональное назначение.
Регистр sp всегда указывает на вершину стека, то есть содержит смещение, по которому в стек был занесен последний элемент. Команды работы со стеком неявно изменяют этот регистр так, чтобы он указывал всегда на последний записанный в стек элемент. Если стек пуст, то значение sp равно адресу последнего байта сегмента, выделенного под
стек.
Оперативная память
0000:0000 |
|
|
|
|
|
|
44 |
|
|
|
|
|
|
Сегмент кода |
|
|
|
|
|
Сегмент данных |
|
|
|
|
|
Сегмент стека |
|
|
|
ss:sp |
|
Вершина стека |
|
|
Нара е е рос а |
|
|
|
|||
|
|
|
|
||
|
|
|
|
|
|
Рис. 4.1. Концептуальная схема организации стека
При занесении элемента в стек процессор уменьшает значение регистра sp, а затем записывает элемент по адресу новой вершины. При извлечении данных из стека процессор копирует элемент, расположенный по адресу вершины, а затем увеличивает значение регистра указателя стека sp. Таким образом, получается, что стек растет вниз, в сторону уменьшения адресов.
Если необходимо получить доступ к элементам не на вершине, а внутри стека, применяют регистр bp. Регистр bp регистр указателя базы стека.
Например, типичным приемом при входе в подпрограмму является передача нужных параметров путем записи их в стек. Если подпрограмма тоже активно работает со стеком, то доступ к этим параметрам становится проблематичным. Выход в том, чтобы после записи нужных данных в стек сохранить адрес вершины стека в указателе базы стека – регистре bp. Значение в bp в дальнейшем можно использовать для доступа к переданным параметрам.
Начало стека расположено в старших адресах памяти. На рис. 4.1 этот адрес обозначен парой ss:ffff. Смещение ffff приведено здесь условно. Реально это значение определяется величиной, которую программист задает при описании сегмента стека в своей программе.
Адресная пара ss:ffff – это максимальное для реального режима значение адреса начала стека, так как размер сегмента в нем ограничен величиной 64
Кб (0ffffh).
Для организации работы со стеком существуют специальные команды записи и чтения.
push источник – запись значения из источника в вершину стека. Интерес представляет алгоритм работы этой команды, который
включает следующие действия (рис. 4.2):
45