4.3.3. Прямая работа с видеопамятью

Все, что изображено на мониторе - и графика, и одновременно присутствует в памяти, встроенной в видеоадаптер. Чтобы изображение появилось на мо­ниторе, оно должно быть записано в память видеоадаптера. Для этой цели отво­дится специальная область памяти, начинающаяся с абсолютного адреса 0B800h:0000h (для текстовых режимов) и заканчивающаяся OB800h:OFFFFh. Все, что программы пишут в эту область памяти, немедленно пересылается в память видеоадаптера. В текстовых режимах для хранения каждого изображенного сим­вола используются два байта: байт с ASCII-кодом символа и байт с его атрибутом, так что по адресу лежит байт с кодом находящимся в верхнем левом углу экрана; по адресу OB800h:0001h расположен атрибут этого сим­вола; по адресу OB800h:0002h - код второго символа в верхней строке экрана и т. д.

Таким образом, любая программа может вывести текст на экран простой ко­мандой пересылки данных, не прибегая ни к каким специальным функциям DOS или BIOS.

dirout.asm

Выводит на экран все ASCII-символы используя прямой вывод на экран.

без исключения,

start:

.model

tiny

 

. code

 

 

.386

 

Будет использоваться регистр ЕАХ

 

 

и команда STOSD.

org

100h

Начало СОМ-файла.

mov

ax,0003h

 

int

10h

Видеорежим 3   (очистка экрана).

eld

 

Обработка строк в прямом направлении.

 

 

Подготовка данных для вывода на экран:

mov

eax,1F201F00h

первый символ 00 с атрибутом 1Рп,

 

 

затем пробел (2011)  с атрибутом Ш

mov

bx,OF20h

Пробел с атрибутом ОРИ.

mov

cx,255

Число символов минус 1.

mov

ctable

Е5:01 : начало таблицы.

Основы программирования для

cloop:

stosd

inc test

jnz

push

mov

x'chg

rep

xchg pop

continue_loop:

loop

al

cx.OFh

continue_loop

CX

cx,80-32

ax, bx

stosw

bx,ax cx

cloop

stosd

собственно вывод на экран

Записать символ и пробел в таблицу ссаЫе. АЬ содержит следующий символ.

Если СХ не кратен 16, продолжить цикл.

Иначе: сохранить значение счетчика.

Число оставшихся до конца строки символов.

Заполнить остаток строки пробелами      : .

с атрибутом (№. Восстановить значение ЕАХ. Восстановить значение счетчика.

Записать последний (256-й) символ и

mov

ax,OB800ri

Сегментный адрес видеопамяти.

mov

es.ax

 

хог

di.di

DI = 0, адрес начала видеопамяти в ES:DI;

mov

si,offset ctable

Адрес таблицы в DS:SI.

mov

cx,15*80+32

15 строк по В0 символов,  последняя строка - 32.

rep

movsw

Скопировать таблицу ctable в видеопамять.

ret

 

Завершение СОМ-файла.

 

 

Данные для вывода на экран начинаются сразу

 

 

за концом файла.   В ЕХЕ-файле такие данные^

 

 

определяют в сегменте

end

start

 

ctable:

В указанной программе при подготовке данных для копирования в видеопа­мять учитывалось следующее: в архитектуре Intel при записи слова (или двойно­го слова) в память старший байт располагается по старшему адресу. Так что при записи в память двойного слова сначала записывается самый младший байт 00h (ASCII-код текущего символа), потом lFh, используемый в этом примере атрибут, далее 20h (код пробела) и лишь затем, по самому ад­ресу, - самый старший байт, lFh, атрибут для этого пробела. Кроме того, в дан­ном примере использовались некоторые 32-битные команды (MOV и STOSD). Ими можно пользоваться из 16-битной программы (разумеется, если процессор 80386 и выше), но не стоит этим злоупотреблять, потому что каждая из команд оказывается длиннее на 1 байт и выполняется дольше на 1 такт.