Ассемблер. Учебное пособие
..pdf• далее – строка, прочитанная с клавиатуры и заканчивающаяся кодом возврата каретки 0Dh.
Int 21H, функция 0СH, сбросить буфер и ввести символ Вызов: AH = 0Сh
AL = номер функции ввода (01h, 06h, 07h, 08h, 0Ah) DS:DX = если 0Ah
Возврат: AL = код символа, если 01h, 06h, 07h, 08h
ничего, если 0Ah.
Очищает буфер клавиатуры, а затем активизирует заданную функцию ввода с клавиатуры, что позволяет программе отменить свойство упреждающего ввода системы MS-DOS.
Далее приводится пример библиотеки макроопределений для работы с клавиатурой.
GetCharBIOS MACRO sub ah,ah
int 16h ENDM
KeyPressedBIOS MACRO mov ah, 01h
int 16h ENDM
GetEchoCharDOS MACRO
LOCAL exit mov ah, 01h int 21h
or al,al jne exit int 21h exit:
ENDM
GetNoEchoCharD MACRO
LOCAL exit mov ah,8 int 21h
or al,al
53
jne exit int 21h exit:
ENDM
GetCharDOS MACRO
LOCAL exit mov ah,7 int 21h
or al,al jne exit int 21h exit:
ENDM
KeyPressedDOS MACRO mov ah,6
mov dl,-1 int 21h ENDM
;Func – номер функции (01h,06h,07h,08h,0Ah)
ClearBuf MACRO Func mov ah,0Ch
mov al,Func int 21h ENDM
После расширения всех приведенных выше макроопределений код введенного символа будет находиться в регистре AL.
Если клавиатура ПК является в большинстве случаев стандартным устройством ввода информации, то для вывода чаще всего используется дисплей. Косвенно эта тема была уже затронута, когда рассматривался ввод символа с эхо, но для управления выводом информации на дисплей требуется более детальное изучение принципов работы устройства и функций прерываний BIOS и DOS.
54
5. Вывод информации на дисплей ПК
5.1. Общие сведения
Дисплей является неотъемлемой частью любого персонального компьютера, осуществляя вывод информации в текстовом и графическом видах, в цвете или в черно-белом варианте. Дисплей подключается к ПК посредством специальной платы, адаптера. BIOS позволяет работать со следующими типами адаптеров MDA адаптер монохромного дисплея, CGA цветной графический адаптер, EGA улучшенный графический адаптер, видеографическая матрица VGA. Все адаптеры могут работать в двух режимах, текстовом или графическом, имеющих различные разрешения, которые определяются максимальными количествами символов или пикселов по вертикали и горизонтали. Самый простой, с точки зрения вывода информации, является тестовый режим с двумя возможными стандартными разрешениями 40*25 или 80*25, т.е. реализуется вывод информации по 40 или 80 символов в 25 строках.
В текстовом режиме выводимый символьный набор стандартизован и представляет собой полную таблицу ASCII – 256 символов. Начальная позиция курсора определена так, чтобы она находилась в верхнем левом углу экрана. Все адаптеры используют буфер, в котором отображаются все данные выводимые на экран. Экран периодически регенерируется путем сканирования данных, содержащихся в буфере. Адаптер МDA использует в качестве буфера регенерации 4Кбайта памяти, начиная с адреса 0B000h, а другие адаптеры, обладающие как текстовыми, так и графическими возможностями, используют 16Кбайт памяти, начиная с адреса 0B800h. В этом случае буфер разбивается на «страницы», которые обновляются и воспроизводятся независимо друг от друга.
На каждую позицию экрана для изображения символа в буфере отводится 2 байта. Первый байт (четный адрес) содержит ASCII-код символа, который с помощью специального знакогенератора преобразуется в точечный образ символа на экране. Второй байт (нечетный адрес) – это байт атрибута. Отдельные биты этого байта в зависимости от типа адаптера и режима управляют такими характеристиками вывода, как мерцание, яркость, инверсное изображение, цвет символа и фона. Допустимые значения байта атрибута приведены в табл. 5.1 и 5.2.
55
Для режимов вывода информации в цвете младшие четыре бита байта атрибутов устанавливают цвет самого символа (бит 3 включает высокую интенсивность). Следующие три бита устанавливают фон символа. Старший бит включает и выключает мигание. Трехбитовые группы позволяют получить восемь различных комбинаций, а когда добавляется бит высокой интенсивности получается еще восемь цветов – итого в сумме получается 16.
Монохромный адаптер использует байт атрибутов иным образом. В этом байте также биты 0-2 отводятся под основной цвет, а биты 4-6 отвечают за цвет фона. Но из всех возможных значений установок байта атрибута, только в 10 случаях можно получить видимые символы, значения байта атрибута приведены в табл. 5.2.
Часто для ускорения вывода на экран, особенно в монохромном режиме, используют метод так называемого вывода через буфер, не используя прерывания, доступные в системе. Буфер представляет собой линейную байтную структуру, поэтому необходимо вычислить относительный адрес для пары байт, определяющих код символа и его атрибут. Так для режима 80*25, формула для вычисления адреса относительно начала буфера имеет следующий вид:
относительный адрес=((у*50h +х)*2) +(№ страницы*1000h).
Таблица 5.1
Байт атрибута для цветных текстовых режимов
Бит 2 |
Бит 1 |
Бит 0 |
|
|
|
Красный |
Зеленый |
Синий |
|
|
|
0 |
0 |
0 |
|
|
|
0 |
0 |
1 |
|
|
|
0 |
1 |
0 |
|
|
|
0 |
1 |
1 |
|
|
|
1 |
0 |
0 |
|
|
|
1 |
0 |
1 |
|
|
|
1 |
1 |
0 |
|
|
|
1 |
1 |
1 |
|
|
|
Интенсивность
«0» |
«1» |
|
|
|
|
черный |
серый |
|
|
|
|
синий |
светло-синий |
|
|
|
|
зеленый |
светло-зеленый |
|
|
|
|
голубой |
светло-голубой |
|
|
|
|
красный |
светло-красный |
|
|
|
|
фиолетовый |
светло- |
|
фиолетов. |
||
|
||
коричневый |
желтый |
|
|
|
|
белый |
ярко-белый |
|
|
|
56
Байт атрибутов для монохромного адаптера |
Таблица 5.2 |
|||
|
||||
Атрибут |
Binary |
Hex |
Decimal |
|
|
|
|
|
|
Нормальный |
00000111 |
7 |
7 |
|
|
|
|
|
|
Интенсивный |
00001111 |
F |
15 |
|
|
|
|
|
|
Нормальный подчеркнутый |
00000001 |
1 |
1 |
|
|
|
|
|
|
Интенсивный подчеркнутый |
00001001 |
9 |
9 |
|
|
|
|
|
|
Негативный |
01110000 |
70 |
112 |
|
|
|
|
|
|
Нормальный мигающий |
10000111 |
87 |
135 |
|
|
|
|
|
|
Интенсивный мигающий |
10001111 |
8F |
143 |
|
|
|
|
|
|
Нормальный мигающий |
10000001 |
81 |
129 |
|
подчеркнутый |
||||
|
|
|
||
|
|
|
|
|
Яркий мигающий |
10001001 |
89 |
137 |
|
подчеркнутый |
||||
|
|
|
||
|
|
|
|
|
Яркий негативный |
11110000 |
F0 |
240 |
Для вывода символа на монохромный экран посредством видеобуфера можно использовать следующий фрагмент программы:
AL – код символа, выводимого на экран, AH – байт атрибута,
CX – у-координата выводимого символа (№ строки) BX – х –координата (№ столбца)
push ax |
; сохранить в стеке код и атрибут символа |
|
mov ax, 160 |
; |
|
mul |
cx |
; DX:AX = Y*160 |
shl |
bx, 1 |
; умножить х на 2 |
add |
bx, ax |
; BX= Y*160 + X*2 |
mov |
ax, 0b000h |
; ES= сегмент буфера генерации |
mov |
es, ax |
; монохромного адаптера |
pop |
ax |
; восстановить символ и атрибут |
mov |
es:[bx], ax |
; записать их значения в буфер |
Для графического режима программирование адаптеров путем обращения к буферу регенерации значительно сложнее. Это связано с
57
тем, что в зависимости от режима вывода изображения, каждому пикселу соответствует или один или несколько бит буфера регенерации. В более совершенных адаптерах также применяется концепция так называемых битовых плоскостей, когда биты пиксела распределяются по нескольким банкам памяти, отображаемым по одним и тем же адресам.
В отличие от текстовых, в графических режимах буфер регенерации разбит на 2 части. Первая часть буфера содержит данные для четных строк экрана, а вторая – для нечетных (строки нумеруются, начиная с верха экрана). Для графического адаптера четные строки могут занимать память со смещениями от 0000h до 1F3Fh, а нечетные – от 2000h до 3F3Fh. Промежуток между 1F3Fh и 2000h игнорируется.
Рассмотрим вывод графики только для простейшего типа графического адаптера CGA, для примера возьмем монохромный режим 640Х200, где каждому пикселу изображения соответствует 1 бит буфера регенерации. Каждый пиксел имеет координаты, представленные в диапазоне от 0 до 639 и от 0 до 199, при этом позиция 0,0 находится в левом верхнем углу.
Каждая последовательная группа из 80 байт (640 бит) представляет одну строку горизонтальной развертки изображения. Внутри каждого байта биты отображаются один к одному на пикселы, причем старший бит соответствует самому левому пикселу набора из восьми пикселов. Для нахождения относительного адреса координаты (x, y) в буфере регенерации необходимо применить следующую формулу:
относительный адрес = ((у & 1)*2000h) + (y/2*50h) +(x/8).
По данной формуле вычисляется относительный адрес байта, где содержится бит, соответствующий пикселу с координатами (х, у). А затем для изменения необходимого бита надо определить его положение в байте и, используя операцию с маской, изменить его. Для определения положения бита следует использовать следующую формулу:
бит = 7 – (х MOD 8).
Фрагмент программы, вычисляющей значения относительного адреса и бита по приведенным выше формулам, выглядит следующим образом:
table db 80h, 40h, 20h, 10h, 08h, 04h, 02h, 01h ; битовые маски
58
mov |
ax, у-координата |
|
mov bx, x-координата |
||
push bx |
; сохраним х-координату |
|
and |
bx, 7 |
; выделим относительный адрес |
mov |
MASK, [bx+table] ; сохраним маску для бита в MASK |
|
pop |
bx |
|
shr |
bx, 1 |
; разделим х на 8 |
shr |
bx, 1 |
|
shr |
bx, 1 |
|
push ax |
; сохраним у-координату |
|
shr |
ax, 1 |
; разделим у на 2 |
mov |
cx, 50h |
; умножим на 50h |
mul |
cx |
; сохраним в DX:AX |
add |
bx, ax |
; добавим произведение к X/8 |
pop |
ax |
; добавим (Y И 1)* 2000h |
and |
ax, 1 |
; |
jz |
lab |
; |
add |
bx, 2000h |
; |
lab: |
….. |
; BX = относительный адрес в ;видеобуфере. |
Гораздо эффективнее работу с дисплеем ПК можно организовать, используя процедуры обработки прерываний BIOS и DOS, и создавая на их базе собственные процедуры и макроопределения.
BIOS для работы с дисплеем компьютера использует различные функции прерывания Int 10H. Рассмотрим наиболее часто используемые функции этого прерывания.
Int 10H, функция 00H, установить видеорежим Вызов: AH= 00h
AL= номер видеорежима Возврат: ничего не возвращается.
Для различных моделей видеоадаптеров используются различные видеорежимы (табл. 5.3).
При инициализации видеорежима происходит полная очистка содержимого видеобуфера, но если установлен бит 7 в регистре AL, то этого не происходит.
Int 10H, функция 02H, установить курсор в заданную позицию
59
Вызов: |
AH= 02h |
|
|
||
|
|
BH= страница |
|
||
|
|
DH= строка (у-кордината) |
|
||
|
|
DL= столбец (х-координата) |
|
||
Возврат: ничего не возвращается. |
|
||||
|
|
|
Перечень видеорежимов |
Таблица 5.3 |
|
|
|
|
|
||
|
|
|
|
Цвета |
|
Режим |
|
Разрешение |
черно-белый (ч\б) |
Текст\графика |
|
|
|
|
|
или количество |
|
|
|
|
|
цветов |
|
00 H |
|
40 |
* 25 |
ч\б |
текст |
01 H |
|
40 |
* 25 |
16 |
текст |
02 H |
|
80 |
* 25 |
ч\б |
текст |
03 H |
|
80 |
* 25 |
16 |
текст |
04 H |
|
320 |
* 200 |
4 |
графика |
05 H |
|
320 |
* 200 |
ч\б |
графика |
06 H |
|
640 |
* 200 |
ч\б |
графика |
0D H |
|
320 |
* 200 |
16 |
графика |
0E H |
|
640 |
* 200 |
16 |
графика |
10 H |
|
640 |
* 350 |
16 |
графика |
11 H |
|
640 |
* 480 |
2 |
графика |
12 H |
|
640 |
* 480 |
16 |
графика |
13 H |
|
320 |
* 200 |
256 |
графика |
Для каждой страницы в видеобуфере организуется отдельный курсор, и с помощью данной функции можно установить любой из этих курсоров независимо от того, какая страница активна в настоящий момент. Число доступных страниц зависит от адаптера и текущего видеорежима.
Int 10H, функция 03H, получить позицию курсора Вызов: AH= 03h
BH= страница
Возврат: DH= строка (у-кордината) DL= столбец (х-координата)
Возвращает текущую позицию курсора на экране в текстовых координатах. Для каждой видеостраницы организован свой курсор,
60
поэтому с помощью данной функции можно определить положение любого из этих курсоров независимо от того, какая страница активна.
Int 10H, функция 05H, установить видеостраницу Вызов: AH= 05h
АL= страница
0 – 7 для режимов 00-03Н, 07Н, 0DН; 0 – 3 для режима 0ЕН;
0 – 1 для режимов 0F, 10Н Возврат: ничего не возвращается.
Переключение страниц не изменяет их содержимого.
Int 10H, функция 06\07H, инициализировать или прокрутить окно вверх\вниз
Вызов: AH= 06h\07h
AL =число строк прокрутки, если 0, то очищается все
окно
BH= атрибут, используемый для очищаемой области CH= у - координата, верхний левый угол окна
CL= х - координата, верхний левый угол окна DH= у - координата, нижний правый угол окна DL= х - координата, нижний правый угол окна
Возврат: ничего не возвращается.
В видеорежимах, поддерживающих несколько страниц, эта функция влияет только на страницу, отображаемую в настоящий момент на экране.
Int 10H, функция 08H, прочитать символ и атрибут из позиции курсора
Вызов: AH= 08h BH= страница
Возврат: АH= атрибут АL= символ
При поддержке нескольких видеостраниц, символ может быть прочитан с любой страницы.
Int 10H, функция 09H, записать символ и атрибут в позицию курсора
Вызов:
61
CX= коэффициент повторения операции записи Возврат: ничего не возвращается Если функция используется для записи символов в графическом
режиме, и бит 7 BL установлен, то будет выполнена операция ИСКЛЮЧАЮЩЕЕ ИЛИ записываемого символа с содержимым экрана, что очень удобно для записи символа и его последующего стирания.
Int 10H, функция 0АH, записать символ в позицию курсора Вызов: AH= 0Аh
AL= символ
BH= страница
CX= коэффициент повторения Возврат: ничего не возвращается
Записывает символ ASCII в текущую позицию курсора на экране. Символ получает атрибут символа, ранее находившегося в этой позиции.
Int 10H, функция 0ЕH, записать символ в режиме телетайпа Вызов: AH= 0Еh
AL= символ
BH= страница
BL= цвет изображения Возврат: ничего не возвращается
Записывает символ в текущую позицию курсора на экране, после чего выполняет соответствующий инкремент позиции курсора. Символы могут записываться на любую страницу, если поддерживается многостраничность данным режимом.
Аналогично текстовым режимам существуют функции данного прерывания для вывода и чтения графического пиксела.
Int 10H, функция 0СH, записать графический пиксел Вызов: AH= 0Сh
AL= значение пиксела BH= страница
CX= столбец (х-координата)
DX= строка (у-координата) Возврат: ничего не возвращается
Диапазон допустимых значений пикселов определяется видеорежимом. В видеорежимах, поддерживающих только одну страницу, содержимое регистра BH игнорируется.
62