|
Изменение вектора прерывания ⇐ ПредыдущаяСтр 7 из 7 MS-DOS предоставляет две функции 35h и 25h прерывания 21h для чтения и установки вектора прерывания. Функция 35h Выполняет чтение адреса подпрограммы обработки прерывания. · Вызов: ah = 35h al = номер прерывания · Возвращаемое значение: es:bx – указатель на подпрограмму прерывания · Примечание. Функция получает адрес, указанного AL прерывания из таблицы векторов прерываний. BX содержит смещение, а ES сегмент адреса подпрограммы. Пример. mov ah, 35h; номер функции mov al, 21h; номер прерывания int 21h В результате: (BX) = 048B, (ES) = 0DDE. Функция 25h Выполняет занесение нового вектора прерывания. · Вызов: ah = 25h al = номер прерывания ds:dx – указатель на подпрограмму обработки прерывания · Возвращаемое значение: Нет · Примечание. Функция устанавливает адрес прерывания, указанного в al в таблицу векторов прерываний. dx содержит смещение, а ds сегмент устанавливаемой подпрограммы. Дополнительные сведения о структуре DOS и BIOS Прямое обращение к видеопамяти Видеопамять компьютера любой конфигурации расположена в адресном пространстве оперативного запоминающего устройства (ОЗУ). Это позволяет напрямую адресовать видеопамять одним из косвенных способов адресации памяти. Видеопамять занимает адреса с A000h по BFFFh, что составляет 128 Кбайт. Для увеличения объёмов видеопамяти (до 64 Мбайт), она делиться на слои, так что по одному адресу находиться несколько ячеек, которые расположены в разных слоях. Обращение к видеопамяти зависит от видеорежима, который определяет количество точек по горизонтали и вертикали, а так же количество битов, отводимую для хранения кода цвета каждой точки. Графическими режимами управляет видеоадаптер. Более простым для программирования, допускающим простой доступ к видеопамяти, является символьный режим, который мы и рассмотрим подробнее. Для работы в символьном режиме отводится 16 Кбайт памяти, начиная с адреса B800h. Экран делится на 80 столбцов и 25 строк. Общее количество знакомест 80 х 25= 2000. Для каждого знакоместа в видеопамяти отводится два байта: чётный байт – ASCII код символа, нечётный – байт атрибутов. Счёт строк и колонок идёт из верхнего левого угла экрана, в байте b800h:0000h хранится символ выводящийся в нулевой строке и нулевой колонке, в байте b800h:0001h хранится атрибут этого символа. В байте b800h:0002h хранится символ выводящийся в нулевой строке и первой колонке, в байте b800h:0002h хранится атрибут этого символа и т.д. Байт атрибутов имеет следующую структуру:
Для доступа к видеопамяти в текстовом режиме можно использовать непосредственно один из сегментных регистров, например, ES: mov ax, 0b800h; записать в регистр mov es, ax; es адрес начала видеопамяти xor bx, bx; смещение символа от начала видеопамяти mov dh, 00010100b; атрибуты: на голубом фоне красный символ mov dl, 65h; ASCII код символа mov word ptr es:[bx], dx; запись в видеопамять символа и атрибута inc bx; смещение для inc bx; следующего символа Другой способ доступа – размещение сегмента данных фиксировано, в области видеопамяти директивой AT. video segment AT 0b800h CHAR_ATRIB db 4000 dup(?) video ends code segment assume cs: code, ds:video START: mov ax, video mov ds, ax xor si, si mov dl, byte ptr CHAR_ATRIB[si];чтение символа inc si mov dh, byte ptr CHAR_ATRIB[si];чтение атрибута ... Буфер клавиатуры В ОЗУ, начиная с адреса 0040h, находится область данных BIOS, в которой хранится различная системная информация: адреса портов устройств, количество тиков таймера, начиная с полуночи и т.д. В частности, в этой области организован буфер клавиатуры, который способен принять до 15 символов от клавиатуры. Исполняемая программа должна опрашивать этот буфер и извлекать из него символы, иначе буфер переполнится, о чём свидетельствует писк встроенного динамика при нажатии очередной клавиши. Буфер организован как круговой массив, т.е. при достижении конца буфера, он, если возможно начинает заполняться сначала. Два указателя: "голова" и "хвост" определяют состояние буфера. "Голова" показывает на первую свободную ячейку буфера, куда записывается очередной символ, поступивший от клавиатуры. "Хвост" показывает символ, который будет прочитан исполняемой программой при очередном обращении к буферу. Если буфер пуст, оба указателя показывают на одну и ту же ячейку буфера. Адрес "головы" буфера находится по адресу word ptr 0040h:001ah, а адрес "хвоста" по адресу word ptr 0040h:001ch. Если содержимое обоих указателей совпадает, значит клавиши нажаты не были. Эту проверку можно использовать для вызова в программе функции, читающей символ из буфера клавиатуры. Пример выполнения работы Написать программу на ассемблере, выводящую в текущее положение курсора символ @. Следующий символ @ выводить в позицию выше, ниже, левее или правее текущего символа, в зависимости от нажатия клавиш “8”, “2”, “4”, “6” на цифровой клавиатуре. Вывод осуществлять непрерывно с некоторой задержкой. Нажатие клавиши “0” завершает выполнение программы. · Примечание. В программе необходимо вести отсчёт времени для задержки вывода символа @. Для этого необходимо изменить подпрограмму обработки прерывания от таймера 08h. Так как эта подпрограмма выполняет важные операции по управлению компьютером, для получения временного интервала используется прерывание 1Ch. Это прерывание вызывается из подпрограммы обработки прерывания 08h и содержит только команду iret. Предназначено оно специально для пользовательских программ, которым необходимо следить за интервалами отсчёта таймера. Текст программы data segment DIRECT db 1; направление перемещения EXIT db 0; признак завершения программы (не 0) SYM db "@"; символ, выводимый на экран ATRIBUT1 db 14; атрибут символа (жёлтый) ATRIBUT2 db 10; атрибут символа (зелёный) POS dw 3840; позиция начального вывода символа OLD_CS dw?; адрес сегмента старого вектора 1Сh OLD_IP dw?; адрес смещения старого вектора 1Сh data ends
code segment assume cs:code, ds:data ; Подпрограмма обработки прерывания 1Сh NEW_1C proc far push ax; сохранить все регистры push bx push cx push dx push ds push es mov ax, DATA; установить ds на сегмент данных mov ds, ax; основной программы mov ax, 40h; установить es на mov es, ax; сегмент данных bios mov ax, es:[1ch] mov bx, es:[1ah] cmp bx, ax jne m5 jmp back m5: mov al, es:[bx] mov es:[1ch], bx cmp al, 30h jnz m1 mov EXIT, 1 jmp back m1: cmp al, 35h jne m6 mov dl, ATRIBUT1 mov dh, ATRIBUT2 mov ATRIBUT1, dh mov ATRIBUT2, dl jmp back m6: cmp al, 38h; стрелка вверх jz m2 cmp al, 32h; стрелка вниз jz m3 cmp al, 34h; стрелка влево jz m4 cmp al, 36h; стрелка вправо jnz back; неиспользуемая клавиша mov DIRECT, 3 jmp back m2: mov DIRECT, 1 jmp back m3: mov DIRECT, 4 jmp back m4: mov DIRECT, 2 back: pop es pop ds pop dx pop cx pop bx pop ax iret NEW_1C endp ; Подпрограмма очистки экрана CLS proc near push cx push ax push si xor si, si mov ah, 7 mov dl, ' ' mov cx, 2000 CL1: mov es:[si], ax inc si inc si loop CL1 pop si pop ax pop cx ret CLS endp ; Подпрограмма задержки DELAY proc near push cx mov cx, 100 d12: push cx xor cx,cx d11: nop loop d11 pop cx loop d12 pop cx ret DELAY endp ; Подпрограмма вывода символа с заданным атрибутом OUT_SYMBOL proc near push ax push bx mov al, SYM mov ah, ATRIBUT1 mov bx, POS call DELAY mov es:[bx], ax pop bx pop ax ret OUT_SYMBOL endp ; Основная программа START: mov ax, DATA mov ds, ax ; чтение вектора прерывания mov ah, 35h mov al, 1Ch int 21h mov OLD_IP, bx mov OLD_CS, es ; установка вектора прерывания push ds mov dx, offset NEW_1C mov ax, seg NEW_1C mov ds, ax mov ah, 25h mov al, 1Ch int 21h pop ds mov ax, 0B800h mov es, ax call CLS call DELAY p1: cmp EXIT, 0 jne quit cmp DIRECT, 1 jz p2 cmp DIRECT, 2 jz p3 cmp DIRECT, 3 jz p4 mov ax, POS add ax,160 cmp ax, 3999 jg p1 mov POS, ax call OUT_SYMBOL jmp p1 p2: mov ax, POS sub ax, 160 jl p1 mov POS, ax call OUT_SYMBOL jmp p1 p3: mov ax, POS sub ax, 2 jl p1 mov POS, ax call OUT_SYMBOL jmp p1 p4: mov ax, POS add ax, 2 jg p1 mov POS, ax call OUT_SYMBOL jmp p1 quit: call CLS mov dx, OLD_IP mov ax, OLD_CS mov ds, ax mov ah, 25h mov al, 1Ch int 21h mov ax, 4c00h int 21h CODE ends end START Варианты заданий Во всех вариантах задания завершение программы осуществляется при вводе цифры 0. 1. Выводить последовательно цифры от 0 до 9 в одно место экрана. При вводе с клавиатуры какой-либо цифры менять темп вывода. Значение задержки между выводом очередного символа определять следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 2. Выводить в одно место экрана поочерёдно код пробела и код какого-нибудь символа. Задержка между выводом каждого символа определяется нажатием цифровой клавиши следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 3. Выводить в одно место экрана введённый символ до тех пор пока не будет введён другой символ. Менять при выводе атрибут символа циклически от 1 до 15. Для анализа нажатия клавиши использовать вектор 1Ch. 4. Выводить в текущее положение курсора символ #. Следующий символ # выводить в позицию выше, ниже, левее или правее текущего символа, в зависимости от нажатия клавиш “8”, “2”, “4”, “6” на цифровой клавиатуре. Вывод осуществлять непрерывно с некоторой задержкой. Задержка между выводом каждого символа определяется нажатием цифровой клавиши, следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 5. Выводить в текущее положение курсора символ, введённый с клавиатуры. Этот же символ выводить в позицию выше, ниже, левее или правее текущего символа, в зависимости от нажатия клавиш “8”, “2”, “4”, “6” на цифровой клавиатуре. С клавиатуры можно ввести любую латинскую букву, при этом, выводимый символ изменяется на введённый символ. Вывод осуществлять непрерывно с некоторой задержкой. Задержка между выводом каждого символа определяется нажатием цифровой клавиши, следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 6. В программе имеются два циклических счётчика, считающих от 0 до 23 и от 0 до 79. Их значение определяет соответственно строку и столбец для вывода символа на экран. При нажатии какойлибо клавиши на экран выводится символ % в положение, определяемое состоянием счётчиков на момент вывода. Для анализа нажатия клавиши использовать вектор 1Ch. 7. В программе имеется циклический счётчик, считающий от 1 до 6. При нажатии любой клавиши содержимое счётчика преобразуется в ASCII код и выводится в определённое место экрана, после чего счётчик продолжает считать. Для анализа нажатия клавиши использовать вектор 1Ch. 8. Посчитать за какое время процессор выполнить 1 000 000 команд mov DI, SI; add DI, SI; mul SI. Для подсчёта времени использовать вектор 1Ch. Выводить на экран преобразованное в ASCII коды число тиков таймера, затраченное на операцию. 9. Очистить экран. Вывести несколько строк произвольного текста (атрибут 14). Перехватив прерывание печати экрана Print Screen (Int 5h), менять атрибуты всех строк экрана циклически от 1 до 15. Каждое нажатие клавиши Print Screen вызывает изменение атрибута. 10. Выводить ежесекундно в правом верхнем углу экрана системное время “часы:минуты:секунды”. 11. Вывести несколько строк произвольного текста, содержащие лишь латинские буквы. Каждые 10 секунд заглавные буквы сменяются строчными и т. д. 12. В программе имеется циклический счётчик, считающий от 00h до FFh. Его значение преобразуется в ASCII код и выводится в левом верхнем углу экрана через 18 тиков таймера. При нажатии клавиши ‘2’ время вывода уменьшается вдвое, а при повторном нажатии время вывода увеличивается в два раза. Для анализа нажатия клавиши и подсчёта числа тиков таймера использовать вектор 1Ch. 13. Заполнить экран произвольной информацией. Перехватить прерывание 1Ch, по нажатию клавиши ‘1’ осуществить горизонтальный скроллинг всего экрана влево на один столбец, при нажатии клавиши ‘2’ скроллинг вправо на один столбец. 14. Очистить экран. Вывести несколько строк произвольного текста. Перехватить прерывание экрана (Int 5h). Первый вызов этого прерывания располагает строки вертикально, следующий «нормально» и т.д. 15. Очистить экран. Заполнить его произвольной информацией. Перехватить прерывание экрана (Int 5h). Первый вызов этого прерывания переносит строчки верхней половины экрана на место нижних, а нижние на место верхних. Следующий вызов прерывания снова меняет их местами и т.д. 16. Выводить последовательно цифры от 0 до 9 в одно место экрана. При вводе с клавиатуры какой-либо цифры менять темп вывода. Значение задержки между выводом очередного символа определять следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 17. Выводить в одно место экрана поочерёдно код пробела и код какого-нибудь символа. Задержка между выводом каждого символа определяется нажатием цифровой клавиши следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 18. Выводить в одно место экрана введённый символ до тех пор пока не будет введён другой символ. Менять при выводе атрибут символа циклически от 1 до 15. Для анализа нажатия клавиши использовать вектор 1Ch. 19. Выводить в текущее положение курсора символ #. Следующий символ # выводить в позицию выше, ниже, левее или правее текущего символа, в зависимости от нажатия клавиш “8”, “2”, “4”, “6” на цифровой клавиатуре. Вывод осуществлять непрерывно с некоторой задержкой. Задержка между выводом каждого символа определяется нажатием цифровой клавиши, следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 20. Выводить в текущее положение курсора символ, введённый с клавиатуры. Этот же символ выводить в позицию выше, ниже, левее или правее текущего символа, в зависимости от нажатия клавиш “8”, “2”, “4”, “6” на цифровой клавиатуре. С клавиатуры можно ввести любую латинскую букву, при этом, выводимый символ изменяется на введённый символ. Вывод осуществлять непрерывно с некоторой задержкой. Задержка между выводом каждого символа определяется нажатием цифровой клавиши, следующим способом: введённую цифру умножить на 29, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. 21. В программе имеются два циклических счётчика, считающих от 0 до 23 и от 0 до 79. Их значение определяет соответственно строку и столбец для вывода символа на экран. При нажатии какой-либо клавиши на экран выводится символ % в положение, определяемое состоянием счётчиков на момент вывода. Для анализа нажатия клавиши использовать вектор 1Ch. 22. В программе имеется циклический счётчик, считающий от 1 до 6. При нажатии любой клавиши содержимое счётчика преобразуется в ASCII код и выводится в определённое место экрана, после чего счётчик продолжает считать. Для анализа нажатия клавиши использовать вектор 1Ch. 23. Посчитать за какое время процессор выполнить 1 000 000 команд mov DI, SI; add DI, SI; mul SI. Для подсчёта времени использовать вектор 1Ch. Выводить на экран преобразованное в ASCII коды число тиков таймера, затраченное на операцию. 24. Очистить экран. Вывести несколько строк произвольного текста (атрибут 14). Перехватив прерывание печати экрана Print Screen (Int 5h), менять атрибуты всех строк экрана циклически от 1 до 15. Каждое нажатие клавиши Print Screen вызывает изменение атрибута. 25. Выводить ежесекундно в правом верхнем углу экрана системное время “часы:минуты:секунды”.
Вопросы по теме 1. В чём суть концепции прерывания? 2. Как работает система прерывания по вектору? 3. В чём отличие команд ret и iret? 4. Какие способы получения/изменения вектора прерывания Вы знаете? 5. Как вызвать программное прерывание? 6. Какие существуют способы передачи параметров в подпрограмму обработки прерываний и возврата параметров из неё? 7. Какие действия производит процессор при получения запроса на прерывание? 8. В чём отличие команд call и int? Что способствует осуществлению желаний? Стопроцентная, непоколебимая уверенность в своем... ЧТО ПРОИСХОДИТ ВО ВЗРОСЛОЙ ЖИЗНИ? Если вы все еще «неправильно» связаны с матерью, вы избегаете отделения и независимого взрослого существования... Что будет с Землей, если ось ее сместится на 6666 км? Что будет с Землей? - задался я вопросом... ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:
|