Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
прогр.docx
Скачиваний:
23
Добавлен:
21.12.2018
Размер:
2.58 Mб
Скачать

02H/03h - Чтение/запись секторов.

Выполняется чтение секторов в оперативную память компьютера или запись информации из памяти в сектора диска.

Сектор задается для выбранных устройства, дорожки и головки. Программа должна также задать количество читаемых/записываемых секторов.

04h - Проверка секторов.

Функция проверяет сектора на правильность циклической контрольной суммы, CRC (Cyclic Redundancy Check); записи содержимого секторов в память не происходит.

Вывод на принтер (параллельный порт).

BIOS содержит простейшую поддержку принтера - три функции прерывания INT 17h. Это функция 01h - инициализация принтера, 02h - опрос состояния принтера и 00h - вывод символа на принтер.

Поскольку к персональному компьютеру можно подключить несколько последовательных портов, при обращении к принтеру следует указывать номер порта.

Работа с системными часами.

Функции прерывания INT 1Ah обслуживают часы реального времени (RTC), имеющиеся в каждом компьютере. С их помощью можно установить время и дату, опросить текущее состояние часов.

Можно установить на заданное время "будильник" - в нужный момент будет вызвано прерывание "будильника" с номером 4Ah. Обработчик прерывания INT 4Ah может подать звуковой сигнал или вывести на экран предупреждающее сообщение.

Считать время из RTC можно с помощью функции 02h прерывания INT 1Ah. Время записывается в BCD формате следующим образом:

ch – часы;

cl – минуты;

dh – секунды.

Перезагрузка операционной системы INT 19h.

Вызов прикладной программой прерывания INT 19h приведет к перезагрузке операционной системы.

Прямое программирование видеобуфера в текстовом режиме

Распределение адресного пространства

Адресное пространство - это просто набор адресов, которые умеет формировать процессор; совсем не обязательно все эти адреса отвечают реально существующим ячейкам памяти.

Типичная схема использования адресного пространства компьютера приведена на рис. 1.

Рис. 1. Типичное распределение адресного пространства.

Начальный килобайт оперативной памяти занят векторами прерываний, которые обеспечивают работу системы прерываний компьютера, и включает 256 векторов по 4 байта каждый.

Вслед за векторами прерываний располагается область данных BIOS, которая занимает всего 256 байт, начиная с сегментного адреса 40h. В области данных BIOS хранятся данные, используемые программами BIOS в своей работе. Так, здесь размещаются:

- входной буфер клавиатуры, куда поступают коды нажимаемых пользователем клавиш;

- адреса видеоадаптера, а также последовательных и параллельных портов;

- данные, характеризующие текущее состояние видеосистемы (форма курсора и его текущее положение на экране, видеорежим, используемая видеостраница и проч.);

- ячейки для отсчета текущего времени и т.д.

BIOS (от Basic In-Out System, базовая система ввода-вывода) является частью операционной системы, хранящейся в постоянном запоминающем устройстве (ПЗУ BIOS). ПЗУ BIOS располагается на системной плате компьютера и является, таким образом, примером встроенного, или "зашитого" программного обеспечения. В функции BIOS входит тестирование компьютера при его включении, загрузка в оперативную память собственно операционной системы MS-DOS, управление штатной аппаратурой компьютера - клавиатурой, экраном, дисками и прочим.

В области памяти, начиная с адреса 500h, располагается собственно операционная система MS-DOS, которая обычно занимает несколько десятков Кбайт. Программы MS-DOS, как и другие системные составляющие (векторы прерываний, область данных BIOS) записываются в память автоматически в процессе начальной загрузки компьютера.

Вся оставшаяся память до границы 640 Кбайт свободна для загрузки любых системных или прикладных программ. Как правило, в начале сеанса в память загружают резидентные программы (русификатор, антивирусные программы). При наличии резидентных программ объем свободной памяти уменьшается.

Далее следует старшая, или верхняя (upper) память.

Часть адресного пространства старшей памяти отводится для адресации к графическому и текстовому видеобуферам графического адаптера. Графический адаптер представляет собой отдельную микросхему, в состав которой входит собственное запоминающее устройство (видеопамять). Схемы управления видеопамятью настроены на диапазоны адресов A0000h...AFFFFh и B8000h...BFFFFh, входящих в общее с памятью адресное пространство процессора. Поэтому любая программа может обратиться по этим адресам и, например, записать данные в видеобуфер, что приведет к появлению на экране некоторого изображения. Если видеосистема находится в текстовом режиме, а запись осуществляется по адресам текстового видеобуфера, на экране появятся изображения тех или иных символов (букв, цифр, различных знаков). Если же перевести видеосистему в графический режим, и записывать данные в графический видеобуфер, то на экране появятся отдельные точки или линии. Можно также прочитать текущее содержимое ячеек видеобуфера.

Для того чтобы изображение появилось на мониторе, оно должно быть записано в память видеоадаптера. В текстовом режиме для VGA-совместимых систем для видеопамяти отводится адресное пространство начинающееся с логического адреса B800h:0000h и заканчивающееся адресом BF00h:0FFFh. Данная область разбивается на 8 секторов по числу видеостраниц (4 Кбайта на страницу). Постраничное деление адресного пространства видеопамяти в текстовом режиме имеет следующий вид:

B800h:0000h – страница 0, смещение в диапазоне 0000h – 0FFFh

B900h:0000h – страница 1, смещение в диапазоне 0000h – 0FFFh

...........

BF00h:0000h – страница 7, смещение в диапазоне 0000h – 0FFFh

На экране отображается видеобуфер, соответствующий активной странице. В текстовых режимах для изображения каждого символа отводится 2 байта: байт с ASCII-кодом символа и байт с его атрибутом.

По адресу B800h:0000h находится байт с кодом символа (левый верхний угол экрана), а в B800h:0001h – атрибут этого символа; B800h:0002h – код второго символа, а в B800h:0003h – атрибут второго символа и т.д.

При формировании изображения непосредственно в видеобуфере, в обход программ DOS и BIOS, все управляющие коды ASCII теряют свои управляющие функции и отображаются в виде соответствующих символов.

Структура байта атрибутов приведена на рис. 2.

Рис. 2. Структура байта атрибутов

Из рис. 2 следует, что каждый символ может принимать любой из 16 возможных цветов, определяемых сочетанием младших 4-х битов. Биты 4-6 байта атрибутов задают цвет фона под данным символом. Последний бит 7, в зависимости от режима видеоадаптера, определяет либо яркость фона под данным символом (тогда фон также может принимать 16 разных цветов), либо мерцание символа (устанавливается DOS по умолчанию).

При загрузке машины устанавливается стандартная палитра, коды цветов которой приведены в табл. 1. Переключение назначения бита 7 осуществляется подфункцией 03h функции 10h прерывания int 10h.

Табл. 1. Коды цветов стандартной палитры

Код

Цвет

Код

Цвет

0h

Чёрный

8h

Серый

1h

Синий

9h

Голубой

2h

Зелёный

0Ah

Салатовый

3h

Бирюзовый

0Bh

Светло-бирюзовый

4h

Красный

0Ch

Розовый

5h

Фиолетовый

0Dh

Светло-фиолетовый

6h

Коричневый

0Eh

Жёлтый

7h

Белый

0Fh

Ярко- белый

 

Двухбайтовые коды символов записываются в видеобуфер в том порядке, в каком они должны появиться на экране: первые 80*2 байт соответствуют первой строке экрана, вторые 80*2 байт – второй и т.д. При этом переход на следующую строку экрана определяется не управляющими кодами возврата каретки и перевода строки, а размещением кода в другом месте видеобуфера.

Для того чтобы из программы получить доступ к видеобуферу, надо занести в один из сегментных регистров данных сегментный адрес видеобуфера. После этого, задавая те или иные смещения, можно выполнить запись в любые места (ячейки) видеобуфера. Вычислить смещение ячейки в координатах "строка-столбец" (row, clm) можно так:

VidAdd r= (row*160) + (clm*2)

При большом объёме выводимых данных, информационный кадр формируется заранее в буфере пользователя, располагающегося в сегменте данных программы.

Пример: Запись строки в видеобуфер 0-страницы.

;Очистка экрана

;Настроим сегментный регистр ES на страницу 0 видеобуфера, а

; ds на сегмент данных

mov ax,0B800h

mov es,ax

;Перешлём в видеобуфер строку символов, настроив

; соответствующим образом регистры si, di и cx

mov si,offset msg ;Смещение источника

mov di,160*12+36*2 ;Смещение приёмника (36 столбец 13 -ой

; строки),

mov cx,msglen ;Число пересылаемых байт

cld ;Просмотр вперёд

rep movsb ;Переслать строку символов с атрибутами

;в видеобуфер

;Останавливаем программу для наблюдения результата (иначе

;после завершения программы запрос DOS на ввод команды

;может затереть выведенную информацию)

mov ah,01h

int 21h

;Поля данных в сегменте данных программы. Символы и

;атрибуты: 0B0h – cветло-бирюзовый по чёрному,

;0E4h –красный по жёлтому

msg db ‘*’,0B0h,’T’,0E4h,’E’,0E4,’S’,0E4,’T’,0E4,’*’,0B0h

msglen=$-msg

Если выводимые символы имеют одни и те же атрибуты, то способ формирования полей данных, предназначенных для прямой записи в видеопамять, упрощается.

Например, если необходимо осуществить вывод символов текста из сегмента данных с единственным атрибутом 0E4h, то нужно изменить код следующим образом:

;Настроим сегментный регистр ES на страницу 0 видеобуфера, а ds

;на сегмент данных

mov ax,0B800h

mov es,ax

mov si,offset msg ;Смещение источника

mov di,160*12+36*2 ;Смещение приёмника (36 столбец 13 –ой

;строки),

mov cx,msglen ;Число пересылаемых байт

cld ;Просмотр вперёд

mov ah,0E4h ;Атрибут выводимых символов 0E4h –

;красный по жёлтому

cycle:

lodsb ;Загрузка в al очередного символа (al ← ds:si)

stosw ;Выгрузка “символ + атрибут” из ах в

;видеобуфер (ax→es:di)

loop cycle ;Повторить msglen раз

;Поля данных в сегменте данных программы.

msg db ‘*TEST*’

msglen=$-msg

Программы, в которых осуществляется просмотр произвольных видеостраниц, на которые предварительно записана информация способом прямого программирования видеобуфера, удобно писать с применением функции 05h int 10h BIOS.

Организация памяти в графическом режиме 12h

Видеопамять в графическом режиме 12h организована следующим образом:

начало видеобуфера находится по адресу 0A0000h.

память организована в виде битовых матриц.

В режиме 12h этих матриц четыре. Каждому пикселю экрана соответствует один бит каждой из битовых матриц. Таким образом каждой адресуемой ячейке видеопамяти - байту - соответствует восемь пикселей. Значение цвета пикселя получается как результат объединения значений соответствующего ему бита всех битовых матриц.

Режим 12h имеет разрешающую способность - 640х480 пикселов. В видеопамяти задействованы все четыре цветовых слоя. Структура видеопамяти показана на рисунке 3.

Рис. 3. Структура видеопамяти режима 12h.

Формулы, используемые для вычисления битов, управляющих данным пикселом экрана, соответствуют формулам режима 10h.

Графический режим 13h

Графический режим 13h (320*200 пикселей, 256 цветов) представляется значительно более простым для программирования. Видеобуфер в этом режиме располагается также по адресу 0A0000h, однако каждому экранному пикселю соответствует один байт видеобуфера. Иными словами, запись в видеопамять байта означает установку цвета (в диапазоне 0..255) экранного пикселя.

Так как байты-пиксели располагаются в памяти последовательно, непосредственно один за другим, вычисление адреса пикселя в памяти по заданным координатам полностью эквивалентно вычислению адреса символа в текстовом режиме.

Этот режим (12h), поддерживается только VGA. Он обеспечивает 256 цветов при разрешающей способности 320х200 пикселов.

Структура видеопамяти приведена на рис. 4. Как видно из рисунка, в данном случае видеопамять организована линейно. Каждый пиксел определяется одним байтом.

Рис. 4. Структура видеопамяти в режиме 13h.

Следующая формула позволяет определить смещение от начала видеопамяти байта, управляющего пикселом с координатами (x,y):

Смещение байта = 140h*y+x

0А0000

0А0000+

140h

0A0141

0A0141+

140h

masm

model small

.stack 100h

.data

array dw 15 dup (?)

; 10 2

; 65 2

; 5 64

; 70 1

; 98 42

A1 dw ? ;элемент для поиска

failed db 0ah,0dh,'Net takogo elementa v massive!','$'

success db 0ah,0dh,'Takou element v massive prisutstvyet ','$'

foundtime db 0 ;количество найденных элементов

fnd db " raz(a)",0ah,0dh,'$'

mes2 db 13,10,'Vvedite element massiva [','$'

mes3 db 'Vvedite element dlya poiska',13,10,'$'

mes4 db ']',13,10,'$'

mm1 db ?

mm2 db ?

mm3 db ?

.code

start:

mov ax,@data

mov ds,ax

mov dx,offset mes3

mov ah,09h ;функция Dos вывода сообщения на

int 21h

xor ax,ax

mov ah,1h

int 21h

sub al,'0'

mov al,al

xor ax,ax

mov si,0 ;si=столбцы в матрице

mov bx,0 ;bx=строки в матрице

mov cx,5 ;число для внешнего цикла (по строкам)

external: ;внешний цикл по строкам

push cx ;сохранение в стеке счетчика внешнего цикла

mov cx,2 ;число для внутреннего цикла (по столбцам)

mov si,0

iternal:

mov dx,offset mes2

mov ah,09h ;функция Dos вывода сообщения на

int 21h

xor ax,ax

mov ax,bx ;выводим на экран номер строки в массиве. Номер

;строки хранится в bx

mov dh,3

div dh

add al,'0'

mov byte ptr [mm1],al

mov byte ptr [mm1+1],'$'

mov dx,offset mm1

mov ah,09h ;функция Dos вывода сообщения на

int 21h

mov dl,':' ;ставим двоеточие после номера строки

mov byte ptr [mm2],dl

mov byte ptr [mm2+1],'$'

mov dx,offset mm2

mov ah,09h ;функция Dos вывода сообщения на

int 21h

mov dx,si ;после запятой выводим номер столбца, элемент

;которого вводим. Номер столбца хранится в si

add dx,'0'

mov byte ptr [mm3],dl

mov byte ptr [mm3+1],'$'

mov dx,offset mm3

mov ah,09h

int 21h

mov dx,offset mes4

mov ah,09h

int 21h

xor ax,ax

mov ah,1h

int 21h

sub al,'0'

xor dx,dx

mov dh,al

mov al,array[bx][si]

;сравниваем содержимое текущего элемента в массиве

;с искомым элементом в dh:

cmp dh,array[bx][si]

jne here ; если значение в массиве и значение в dh совпали, то

inc foundtime ;увеличиваем счетчик совпадений

here:

inc si ;иначе - цикл по строке

loop iternal

jcxz move_next ;просмотрели строку?

move_next: ;продвижение в матрице

pop cx ;восстанавливаем CX из стека (5)

add bx,3 ;передвигаемся на следующую строку

loop external ;цикл (внешний)

cmp foundtime,0h ;сравнение числа совпавших с 0

ja eql ;если больше 0, то переход на метку eql, иначе, если

not_equal: ;нет элементов, совпавших с искомым

mov ah,09h ;вывод сообщения на экран

mov dx, offset failed

int 21h

jmp exit ;на выход

eql: ;есть элементы, совпавшие с искомым

mov ah,09h ;вывод сообщений на экран

mov dx,offset success

int 21h

mov ah,02h

mov dl,foundtime

add dl,30h

int 21h

mov ah,09h

mov dx,offset fnd

int 21h

exit: ;выход

mov ax,4c00h ;стандартное завершение программы

int 21h

end start