Методическое руководство к курсовой работе по дисциплине Assembler ibm pc содержание
Вид материала | Руководство |
СодержаниеProc resident ;Основная процедура Proc new_09h |
- Учебно-методическое пособие по выполнению курсовой работы по дисциплине «Комплексный, 276.48kb.
- Дейт К. Д27 Руководство по реляционной субд db2/ Пер с англ и предисл. М. Р. Когаловского, 4309.37kb.
- Методическое пособие по дисциплине «информатика» (2семестр), 838.3kb.
- Методическое пособие по курсовой работе Для студентов Современной Гуманитарной Академии, 63.65kb.
- Пособие предназначено для студентов, выполняющих курсовые работы по дисциплине «Направления, 589.33kb.
- Руководство к выполнению курсовой работы по дисциплине «Финансы предприятий», 244.13kb.
- Методические указания к курсовой работе по дисциплине «Материаловедение и ткм», 699.8kb.
- Пояснительная записка к курсовой работе на тему: «Активный полосовой фильтр» по дисциплине, 342.06kb.
- Всвязи с имеющими место случаями невыполнения требований задания к курсовой работе, 112.75kb.
- Курс. 01;Мпк. 01;3 методическое пособие по курсовой работе методика воспитательной, 230.31kb.
Proc resident ;Основная процедура
jmp init ;Переход на инициализацию
;Данные резидентной секции и место для хранения перехватываемых векторов
old_09h dd 0
old_2Fh dd 0
string db '***'
time db '00:00:00' ;Формат вывода
db '***' ;’$’
strlen = $-string
ten db 10
;Прикладной обработчик клавиатуры new_09h, анализирующий скан-коды клавиш. Все коды, кроме
;кода 4Еh (сер. плюс) передаются в системный обработчик. Нажатие клавиши "сер. плюс" приводит
;к выдаче конца прерывания EOI и вызову процедуры получения системного времени DOS 2Ch.
;Время выводится на экран с использованием средств BIOS
^
Proc new_09h
pusha ;Сохраним регистры
push es
push ds
in al,60h ;Введём скан-код
cmp al,4Eh ;Скан-код серого плюса
je hotkey ;Да, на активизацию резидента
pop ds ;Восстановим регистры
pop es
popa
jmp [dword cs:old_09h] ;В системный обработчик без возврата
hotkey: sti ;Разрешим аппаратные прерывания с более высоким приоритетом,
;(в данном случае таймеру).
;Получим системное время (двоичный код) с помощью функции DOS 2Ch
;Возврат: CH- часы,CL- минуты, DH- секунды
mov ah,2Ch
int 21h
;Преобразуем каждую из составляющих системного времени в двухразрядный десятичный код с
;занесением в строку time
mov al,ch ;Часы
lea bx,[cs:time] ;Адрес позиции в строке
call bin_decasc ;Преобразуем в десятичные символы
mov al,cl ;Минуты
lea bx,[cs:time+3]
call bin_decasc
mov al,dh ;Секунды
lea bx,[cs:time+6]
call bin_decasc
;***
;Выведем время на экран функцией BIOS 13h, в режиме 0. После записи курсор принимает исходное
;положение (т.е. вывод следующей строки начинается с той же позиции, что и в предыдущем случае).
;Так как адрес буфера строки для функции 13h задаётся значением ES:BP, установим ES=CS
push cs
pop es
mov ah,13h ;Функция BIOS 13h
mov al,0 ;Режим 0. Строка содержит только коды символов
mov bh,0 ;0- страница
mov bl,0Ch ;Розовый по чёрному
mov cx,strlen
mov dh,10 ;Номер строки (из 25)
mov dl,25 ;Номер столбца (из 80)
mov bp,offset string ;Поместим адрес буфера в ES:BP
int 10h ;Прерывание BIOS
;***
;Разрешим дальнейшую работу клавиатуры
cli ;Запретим аппаратные прерывания
in al,61h ;Ввод содержимого порта 61h
or al,80h ;Подтвердим приём кода, добавив "1" к
out 61h,al ;старшему разряду байта
and al,7Fh ;Снова разрешим работу клавиатуры,
out 61h,al ;сбросив старший бит в порте 61h
;Пошлём в контроллер обработки прерываний команду EOI
mov al,20h
out 20h,al
;Восстановим регистры и выйдем из прерывания
pop ds
pop es
popa
iret
Proc bin_decasc
;Процедура преобразования 8-разрядного двоичного кода в двухразрядный десятичный ASCII-
;формат. Вход: al-двоичный код, BX- адрес записи десятичной ASCII- цифры
xor ah,ah
div [cs:ten] ;al=quot ax/10, ah=rem ax/10
add al,'0' ;Преобразуем в ASCII- символ старший разряд
mov [cs:bx],al ;Запись старшего разряда
add ah,'0'
mov [cs:bx+1],ah ;Запись младшего разряда, образованного остатком от деления
ret
Endp bin_decasc
Endp new_09h
Proc new_2Fh
;Прикладной мультиплексный обработчик прерывания new_2Fh
cmp ah,0C8h ;Наша функция?
jne out_2Fh ;Не наша, - на выход
cmp al,00h ;Подфункция проверки на повторную установку
je i_here ;Да, сообщим о невозможности повторной установки
cmp al,01h ;Подфункция выгрузки?
je uninst ;Да, на выгрузку
jmp short out_2Fh ;Неизвестная подфункция, на выход
i_here: mov al,0ffh
iret
out_2Fh: jmp [dword cs:old_2Fh] ;Переход в следующий по цепочке обработчик
;прерывания 2Fh
;Выгрузим программу из памяти, предварительно восстановив все перехваченные векторы
uninst: push ds
push es
push dx
mov ax,2509h ;Восстановим вектор 09h
lds dx,[cs:old_09h]
int 21h
mov ax,252Fh ;Восстановим вектор 2Fh
lds dx,[cs:old_2Fh]
int 21h
;Получим из PSP адрес собственного окружения и выгрузим его
mov es,[cs:2Ch] ;es <- сегментный адрес окружения программы
mov ah,49h ;Функция освобождения блока памяти
int 21h
;Выгрузим теперь программу из памяти вместе с PSP
push cs
pop es ;es снова указывает на начало PSP
mov ah,49h ;Функция освобождения блока памяти
int 21h
pop dx
pop es
pop ds
iret
Endp new_2Fh
Endp resident
Proc init
;Секция инициализации
;- Выполняется проверка на наличие в памяти первого экземпляра резидента.
;- Если первый экземпляр не обнаружен, то независимо от вида запускающей программу команды
(с опцией или без неё) происходит переход на метку ОК с установкой программы в памяти
;- При обнаружении первого экземпляра программы начинается сравнение опции команды с
;ожидаемой
;- Если результат сравнения оказался отрицательным (опция есть, но другая), программа завершается
;выводом сообщения о невозможности повторной установки
;- При идентичности опции ожидаемой резидент выгружается из памяти с выводом
;соответствующего сообщения
mov ax,0C800h ;Запрос на наличие в памяти первого
int 2Fh ;экземпляра программы
cmp al,0ffh ;Вернулся код 0ffh?
jne ok ;Нет, данная программа в памяти отсутствует. Выполним её
;установку, перейдя на метку оk
;Первый экземпляр обнаружен. Была ли у команды опция 'off'?
mov cl,[es:80h] ;Получим длину хвоста из PSP
cmp cl,0 ;Длина хвоста = 0?
je fin ;Да, программа запущена без него
xor ch,ch ;Пусть сх=cl=длина хвоста
mov di,81h ;Адрес хвоста es:di в PSP
mov al,' ' ;Уберём пробелы из начала хвоста
repe scasb ;Сканируем хвост (al - dst), пока пробелы
dec di ;di- первый символ после пробела
mov cx,3 ;Ожидаемая длина опции
mov si,offset option ;Адрес ожидаемой опции (option) ds:si
repe cmpsb ;Сравниваем введённую опцию с ожидаемой
jne fin ;Опции не совпали. На выход
mov ax,0C801h ;Опции совпали, пошлём в резидентную
int 2Fh ;программу команду (al=01) на выгрузку. По окончанию
mov dx,offset msg3 ;выгрузки выведем сообщение об этом
jmp fin1
fin: mov dx,offset msg2 ;Попытка вторичной установки
fin1: mov ah,09h
int 21h
mov ax,04C00h ;Функция DOS 4Сh: выход из программы
int 21h ;Вызов DOS. Останов
;Первой экземпляр (резидент) отсутствует. Установим программу
ok: mov ax,3509h ;Чтение и сохранение вектора 08h
int 21h
mov [word cs:old_09h],bx
mov [word cs:old_09h+2],es
mov ax,352Fh ;Чтение и сохранение вектора 2Fh
int 21h
mov [word cs:old_2Fh],bx
mov [word cs:old_2Fh+2],es
mov ax,2509h ;Установка обработчика 08h
mov dx,offset new_09h
int 21h
mov ax,252Fh ;Установка обработчика 2Fh
mov dx,offset new_2Fh
int 21h
mov ah,09h
mov dx,offset msg1 ;Сообщение об успешной установке программы
int 21h
mov ax,3100h ;Завершим программу, оставив её
mov dx,(init-resident+10Fh)/16 ;резидентной в памяти
int 21h