ЛАБОРАТОРНАЯ РАБОТА 3
Тема 7. Знакомство с некоторыми функциями 10 прерывания BIOS.
Тема 8. Процедуры в языке Ассемблер
ПРЕРЫВАНИЯ ДЛЯ СЛУЖБ ROM BIOS
Двенадцать прерываний ROM BIOS распадаются на пять групп:
— 10Н, 13Н, 14Н, 15Н, 16Н, 17Н прерывания обслуживают конкретные перефирийные устройства;
— 11Н, 12Н прерывания сообщают о конфигурации компьютера;
— 1АН работает с часами времени-даты;
— 5Н прерывание выполняет функцию печати экрана;
— 18Н, 19Н специальные службы.
10H прерывание BIOS
Прерывание 10H обеспечивает управление всем экраном. В регистр АН устанавливается код, определяющий функцию прерывания. Команда сохраняет содержимое регистров ВХ, СХ, DX, SI, BP.
Некоторые функции видеослужбы 10H ROM BIOS
00Н — установить видеорежим;
01Н — установить размер курсора;
02Н — установить положение курсора;
03Н — прочитать положение курсора;
06Н — прокрутить страницу вверх;
07Н — прокрутить страницу вниз;
08Н — прочитать знак и атрибут;
09Н — записать знак и атрибут;
0АН — записать знак с текущим атрибутом;
13Н — записать строку символов;
0EH – режим телетайпа.
Ознакомиться с возможными функциями 10 прерывания и их использованием можно по «Электронному справочнику». Для этого запустить программу help.exe в каталоге ASM, выбрать пункт в меню «Указатель функций DOS/BIOS», выбрать <прерывания и сервис ROM-BIOS>, <INT 10H Видео сервис>, <детали видеосервиса>.
Данный материал поможет разобраться с работой предлагаемой программы, которая запрашивает пароль и отображает его в шифрованном виде при вводе с клавиатуры. Если пароль введен верно, на экране появляется сообщение «Вы правы !».
Процедуры
Процедурой (подпрограммой) называется код, из которого можно возвратиться так, как будто код вводится в ту же точку, из которой осуществлялся переход. Переход к процедуре называется вызовом процедуры, возврат назад в вызывающую программу возвратом из процедуры. Процедуры обеспечивают основное средство разделения на модули, что значительно облегчает программирование.
При вызове процедуры необходимо выполнить следующие условия:
- Запомнить адрес следующей за вызовом команды, чтобы можно было осуществлять возврат.
- Запомнить регистры, используемые в процедуре до изменения их содержимого, а перед выходом восстановить.
- Иметь в процедуре средства взаимодействия или разделения данных с вызываемой программой и другими процедурами.
Первое требование удовлетворяется наличием специальных команд вызова и возврата.
Директивы PROC и ENDP
Сегмент кода содержит выполняемые команды. Кроме этого этот сегмент включает в себя один или несколько процедур, определенных через директиву PROC. Имя процедуры уникально.
<Name> PROC [NEAR/FAR]
; NEAR — в пределах первого сегмента
; FAR — за пределами сегмента.
Тело процедуры
RET ; выход из процедуры
<Name> ENDP ; конец процедуры
Оформляются процедуры в программе следующим образом.
codesg segment para
begin proc far
. . .
call b10 ; вызовы процедур
call c10
ret
begin endp
b10 proc near ; описание процедуры
. . .
ret
b10 endp
c10 proc near ; описание процедуры
. . .
ret
c10 endp
codesg ends
end begin
FAR информирует систему, что данный адрес является точкой входа для выполнения.
NEAR указывает, что элементы процедуры находятся в этом кодовом сегменте. Может быть опущен.
1) Внутрисегментный прямой вызов
CALL CHECK ;SP-2 IP®SP IP= IP + смещение
2) Внутрисегментный косвенный
CALL AX ;SP-2 IP®SP IP= смещениe
3) Межсегментный прямой
CALL FAR PTR CHECK
;SP-2 CS->SP SP-2 IP->SP
новые CS и IP содержатся в самой команде
4) Межсегментный косвенный
CALL EXIT
новые CS и IP содержатся в ячейке памяти EXIT
Когда Ассемблер встречает команду CALL PROG_NAME, он смотрит на определение PROG_NAME: FAR оно или NEAR и генерирует далекий вызов или близкий.
1) Внутрисегментный возврат RET (RETN) ;IP¬ SP SP+2
2) Внутрисегментный возврат с данным
RET <числ.конст.>
;IP¬ SP SP+2 SP+<числ. конст.>
3) Межсегментный возврат RET (RETF)
;IP¬SP SP+2 CS¬SP SP+2
4) Межсегментный возврат с данным
RET <числ. конст.>
;IP¬SP SP+2 CS¬SP SP+2 SP+<числ. kонст.>
Инструкция RET Ассемблера смотрит на определение процедуры, содержащей эту инструкцию, осуществляет FAR RET или NEAR RET.
Флаги не меняются.
Не существует короткого вызова CALL. Если вызов производится обращением вперед, то перед оператором нужного ввести модификатор NEAR PTR для внутрисегментного прямого вызова или FAR PTR для межсегментного прямого вызова.
Если процедура в том же сегменте, что и вызов, то используется определение <имя_проц.> PROC NEAR, если в другом сегменте кода или в другом модуле, то <имя_проц.> PROC FAR. В последнем случае имя процедуры необходимо объявить в операторах EXTRN и PUBLIC.
Второе требование насчет запоминания и восстановления регистров. Чтобы не беспокоиться за содержание регистров используемых в процедуре, необходимо запомнить их в стеке.
sub_test proc near
push ax
push bx
push cx
…….
pop cx
pop bx
pop ax
ret
sub_test endp
Если какой — либо регистр используется для возврата значения, то его можно не запоминать.
Третье требование — взаимодействие процедур.
В связи с этим возникает вопрос о способе обмена информации между различными процедурами, т.е. о способе передачи параметров в процедуру и возврате по окончанию ее работы.
а) Передача параметров через глобальные переменные.
data segment
ary dw 100 dup(?)
count dw ?
sum dw ?
data ends
Зная имя переменной, всегда можно организовать доступ к ней. Если процедура находится в отдельном исходном модуле, то она может обращаться к исходным данным, описанным в другом модуле, если в вызывающей программе есть объявление этих переменных как PUBLIC:
PUBLIC ARY, COUNT, SUM,
а в исходном модуле процедуры директива
EXTRN ARY: WORD, COUNT: WORD, SUM: WORD
б) Данные можно разместить в общей области, описав сегменты данных с параметром common
data segment common
ary dw 100 dup(?)
count dw ?
sum dw ?
data ends
Можно применять и другие имена, не совпадающие в исходном и вызываемом модуле, но размер области памяти и имя сегмента данных должны быть одинаковы.
в) Передача данных через регистры
Если количество данных, передаваемых в процедуру, не велико то их модно передавать через регистры МП.
г) Передача адресов параметров в процедуру
Построение таблицы параметров и передача ее адреса через регистр.
Зарезервировать таблицу для адресов
table dw 3 dup(?) ; три слова для адресов
……………
mov table, offset ary передача адресов
mov table+2, offset count (инициализация
mov table+4, offset sum таблицы)
mov bx, offset atble ; занести адрес таблицы в bx
call proadd
. . . .
proadd prog far
push ax
push cx
push si
push di
mov si, [bx] ; загружает адрес ary в si
mov di, [bx+2] ; di — count
mov cx, [di]
mov di, [bx+4] ; di — адрес sum результата
д) Передача параметров через стек
Перед вызовом данные помещаем в стек. Можно записывать значения глобальных переменных, чтобы не портить оригиналы. Если же необходимо изменить их значение, то в стек помещаются их адреса.
Для доступа к данным в стеке используется регистр BP, который по умолчанию определяет косвенный адрес по отношению к сегменту стека SS.
code segment
. . .
mov ax,offset ary
push ax
mov ax,count
push ax
mov ax,offset sum
push ax
call near ptr procadd
. . .
procadd proc near
push bp
mov bp,sp
mov si,[bp+8] ;ary
mov cx,[bp+4] ;count
mov dx,[bp+2] ;sum
. . .
pop bp
ret 6
procadd endp
code ends
Если в процедуре помещаются данные в стек, то обращаться к ним через BP нужно с отрицательным смещением [BP-2].
ВЫПОЛНЕНИЕ РАБОТЫ
- Скопируйте предложенную программу в отдельный файл.
- Ассемблируйте.
- Вызовите TurboDebugger.
- Выполните программу в пошаговом режиме.
- Дополните программу выводом сообщения о неверном вводе пароле.
- Изучите функции 10Н прерывания и их использование.
- Выполните индивидуальное задание. При выполнении обращайтесь к электронному справочнику Help.exe.
title Демонстрация 10 прерывания BIOS (com)
;———————————————
codesg segment para ‘code’
assume cs:codesg, ds:codesg, ss:codesg, es:codesg
org 100h
begin: jmp main
main proc near
call clear_scrin
; вывод сообщения на экран
mov row,09
mov col,10
lea bp, [message] ; адрес строки
mov cx, 15 ;длина строки
call write_string
;Cмещение курсора на конец выведеного сообщения
add col, 18
lea si, cout
wr:
; Установка позиции курсора
mov ah, 02h
mov bh, 00
mov dl, col
int 10h
;ожидание ввода с клавиатуры без эхоотображения
mov ah, 00h
int 16h
cmp al, 0dh ; конец ввода «Enter»
je wr1
; Введенный символ из al записывается в строку cout
mov [si], al
inc si
; выводится на экран в текущую позицию курсора символ ‘*’
mov ah, 09
mov al, ‘*’
mov bh, 00
mov cx, 1
int 10h
inc col
inc coun
cmp coun, 5
jne wr
wr1:
lea si, parol
lea bp, [cout]
wr2:
mov ah, [si]
mov al, [bp]
cmp ah, al
jne q
cmp cl, coun
je wr3
inc si
inc bp
inc cl
jmp wr2
q: ret
wr3: call ok
main endp
ok proc near
call clear_scrin
lea bp,[mess] ;адрес строки
mov cl, 9
call write_string
ret
ok endp
clear_scrin proc near
; Очистка экрана
mov ax, 0600h ; ah=06-прокрутка экрана
; al=00-весь экран
mov bh, 07
mov cx, 0000
mov dx, 184fh
int 10h
ret
clear_scrin endp
write_string proc near
mov ah, 13h ; функция вывода на экран
mov al, 1
mov bh, 00 ; номер видео страницы
mov bl, 12
mov dh, 6 ;координаты по строке
mov dl, 6 ;координаты по столбцу
int 10h
ret
write_string endp
message db ‘Введите пароль: ‘
mess db ‘Вы правы!’
mess1 db ‘Вы ошиблись!’
row db 00
col db 00
cout db 6 dup (‘ ‘)
parol db ‘hello’
coun db 0
codesg ends
end begin
ИНДИВИДУАЛЬНЫЕ ЗАДАНИЯ
- Оформите ввод пароля в рамке. Рамка расширяется при вводе символов. Для рисования рамки используйте коды символов:
DA — Верхний левый угол D9 — Нижний правый угол
BF — Верхний правый угол C4 — Горизонтальная линия
C0 — Нижний левый угол B3 — Вертикальная линия
- Дополните программу: ввод пароля пока не будет введено правильное слово. При каждом неверном вводе выводите сообщение об этом.
- Дополните программу: вводите пароль 3 раза, каждый раз после ввода отображайте введенное слово и сообщайте верно или неверно введен пароль. Затем выход в DOS.
- Дополните программу: измените цвет выводимых на экран символов и при неверном вводе пароля в правом верхнем углу выводите сообщение «Ха-ха, Вы ошиблись !!!».
- Дополните программу: ввод пароля пока не будет введено правильное слово. В случае неверного ввода ошибочный пароль появляется на экране и мигает.
- Дополните программу. При верном вводе пароля он появляется на экране через временную задержку разного цвета.
- Дополните программу. Выведите любое сообщение в 10 строке экрана. Используя скролинг, переместите строку на самую верхнюю строку экрана через одну строку, затирая предыдущую, а затем на самую нижнюю. Для замедления вывода используйте временную задержку. Изменяйте цвет выводимой строки.
- Дополните программу. Введите любую строку и выведете на экран каждое слово разным цветом.
- Дополните программу. Введите строку текста и выведете его по буквам в режиме телетайпа разными по цвету буквами.
- Дополните программу. Введите строку и выведете каждое слово в новой строке со смещением на длину строки.
- Ввести строку текста, включающую русские и английские слова. Подсчитать, каких букв в тексте больше — русских или латинских. Вывести сообщение на экран в цвете.
- Дана строка и некоторое слово. Напечатать те предложения строки, которые содержат данное слово. Слово выделить цветом.
- Дана строка. Напечатать в алфавитном порядке все слова из данной строки.
ВОПРОСЫ К ЗАЩИТЕ ЛАБОРАТОРНОЙ РАБОТЫ
- Прерывания BIOS. Где находятся процедуры обработки прерываний?
- Функции прерывания 10h.
- Определение и назначение процедуры в программе.
- Дальний и ближний вызов процедуры.
- Возврат из процедуры.
Способы передачи параметров в процедуру.