Автор: Пользователь скрыл имя, 22 Октября 2012 в 18:24, курсовая работа
Ассемблером называется машинно-зависимый компилятор, преобразующий специальным образом составленные текстовые строки в машинные инструкции. Как и любой другой компилятор, ассемблер упрощает разработку программ за счет того, что предоставляет пользователю доступ к кодам машинных инструкций и операндам с помощью символьных имен.
Достоинство заключается в том, что, программируя на ассемблере, программист обычно выбирает последовательность машинных инструкций так, чтобы реализовать нужные вычисления с максимальной скоростью при минимальных затратах памяти. С другой стороны, программирование на уровне машинных инструкций – чрезвычайно хлопотное занятие и не может сравниться по скорости разработки с программированием на языках высокого уровня. В этом заключается главный недостаток ассемблера.
Федеральное агентство связи
БФ ГОУ ВПО СибГУТИ
Курсовая работа
по дисциплине «_______»
Выполнил:
Ст-т гр
Пуртов В.
Проверил:
___________
Улан-Удэ, 2005
Ассемблером называется машинно-зависимый компилятор, преобразующий специальным образом составленные текстовые строки в машинные инструкции. Как и любой другой компилятор, ассемблер упрощает разработку программ за счет того, что предоставляет пользователю доступ к кодам машинных инструкций и операндам с помощью символьных имен.
Достоинство заключается в том, что, программируя на ассемблере, программист обычно выбирает последовательность машинных инструкций так, чтобы реализовать нужные вычисления с максимальной скоростью при минимальных затратах памяти. С другой стороны, программирование на уровне машинных инструкций – чрезвычайно хлопотное занятие и не может сравниться по скорости разработки с программированием на языках высокого уровня. В этом заключается главный недостаток ассемблера.
Постановка задачи:
Написать обработчик прерывания от клавиатуры дописанный спереди с целью введения дополнительного пробела при нажатии на клавишу «Б»
Клавиатура содержит Intel-ский микропроцессор, который воспринимает каждое нажатие на клавишу и выдает скан-код в порт A микросхемы интерфейса с периферией, расположенной на системной плате. Скан-код это однобайтное число, младшие 7 битов которого представляют идентификационный номер, присвоенный каждой клавише. На всех машинах, кроме AT, старший бит кода говорит о том, была ли клавиша нажата (бит = 1, код нажатия) или освобождена (бит = 0, код освобождения). Когда эта клавиша нажимается, то в порт A посылается код 10110000, а когда ее отпустили код 00110000. Таким образом, каждое нажатие на клавишу дважды регистрируется в микросхеме 8255. И каждый раз микросхема 8255 выдает подтверждение микропроцессору клавиатуры. AT работает немного по-другому, посылая в обоих случаях один и тот же скан-код, но предваряя его кодом F0Н, когда клавиша отпускается.
Когда скан-код выдается в порт A, то вызывается прерывание клавиатуры (INT 9). Процессор моментально прекращает свою работу и выполняет процедуру, анализирующую скан-код. Когда поступает код от клавиши сдвига или переключателя, то изменение статуса записывается в память. Во всех остальных случаях скан-код трансформируется в код символа, при условии, что он подается при нажатии клавиши (в противном случае, скан-код отбрасывается). Конечно, процедура сначала определяет установку клавиш сдвига и переключателей, чтобы правильно получить вводимый код (это "a" или "A"?). После этого введенный код помещается в буфер клавиатуры, который является областью памяти, способной запомнить до 15 вводимых символов, пока программа слишком занята, чтобы обработать их.
Имеется два типа
кодов символов, коды ASCII и расширенные
коды. Коды ASCII это байтные
числа, которые соответствуют
Второй набор кодов, расширенные коды, присвоен клавишам или комбинациям клавиш, которые не имеют представляющего их символа ASCII, таким как функциональные клавиши или комбинации с клавишей Alt. Расширенные коды имеют длину 2 байта, причем первый байт всегда ASCII 0.
Имеется несколько комбинаций клавиш, которые выполняют специальные функции и не генерируют скан-коды. Эти исключения приводят к заранее предопределенным результатам.
В архитектуре процессоров 80x86 предусмотрены особые ситуации, когда процессор прекращает (прерывает) выполнение текущей программы и немедленно передает управление программе-обработчику, специально написанной для обработки этой конкретной ситуации. Такие особые ситуации делятся на два типа: прерывания и исключения, в зависимости от того, вызвало ли эту ситуацию какое-нибудь внешнее устройство или выполняемая процессором команда. Исключения делятся далее на три типа: ошибки, ловушки и остановы, в зависимости от того, когда по отношению к вызвавшей их команде они происходят. Ошибки происходят перед выполнением команды, так что обработчик такого исключения получит в качестве адреса возврата адрес ошибочной команды (начиная с процессоров 80286), ловушки происходят сразу после выполнения команды, так что обработчик получает в качестве адреса возврата адрес следующей команды, и наконец, остановы могут происходить в любой момент и вообще не предусматривать средств возврата управления в программу.
Команда INT (а также INTO и INT3) используется в программах как раз для того, чтобы вызывать обработчики прерываний (или исключений). Фактически они являются исключениями ловушки, поскольку адрес возврата, который передается обработчику, указывает на следующую команду, но так как эти команды были введены до разделения особых ситуаций на прерывания и исключения, их практически всегда называют командами вызова прерываний. Ввиду того, что обработчики прерываний и исключений в DOS обычно не различают механизм вызова, с помощью команды INT можно передавать управление как на обработчики прерываний, так и исключений.
Как показано в главе 4, программные прерывания, то есть передача управления при помощи команды INT, являются основным средством вызова процедур DOS и BIOS, потому что в отличие от вызова через команду CALL здесь не нужно знать адреса вызываемой процедуры — достаточно только номера. С другой стороны интерфейса рассмотрим, как строится обработчик программного прерывания.
Когда в реальном режиме выполняется команда INT, управление передается по адресу, который считывается из специального массива, таблицы векторов прерываний, начинающегося в памяти по адресу 0000h:0000h. Каждый элемент этого массива представляет собой дальний адрес обработчика прерывания в формате сегмент: смещение или 4 нулевых байта, если обработчик не установлен. Команда INT помещает в стек регистр флагов и дальний адрес возврата, поэтому, чтобы завершить обработчик, надо выполнить команды popf и retf или одну команду iret, которая в реальном режиме полностью им аналогична.
; Пример обработчика программного прерывания
int_handler proc far
mov ax,0
iret
int_handler endp
После того как обработчик написан, следующий шаг — привязка его к выбранному номеру прерывания. Это можно сделать, прямо записав его адрес в таблицу векторов прерываний, например так:
push 0 ; сегментный адрес таблицы
pop es ; в ES
pushf ; поместить регистр флагов в стек
cli ; запретить прерывания
; (чтобы не произошло аппаратного прерывания между следующими
; командами, обработчик которого теоретически может вызвать INT 87h
; в тот момент, когда смещение уже будет записано, а сегментный
; адрес еще нет, что приведет к передаче управления
; в неопределенную область памяти)
; поместить дальний адрес обработчика int_handler в таблицу
; векторов прерываний, в элемент номер 87h (одно из неиспользуемых прерываний)
mov word ptr es:[87h*4], offset int_handler
mov word ptr es:[87h*4+2], seg int_handler
popf ; восстановить исходное значение флага IF
Теперь команда INT 87h будет вызывать наш обработчик, то есть приводить к записи 0 в регистр АХ.
Перед завершением работы программа должна восстанавливать все старые обработчики прерываний, даже если это были неиспользуемые прерывания типа 87h. Для этого надо перед предыдущим фрагментом кода сохранить адрес старого обработчика, так что полный набор действий для программы, перехватывающей прерывание 87h, будет выглядеть следующим образом:
push 0
pop es
; скопировать адрес предыдущего обработчика в переменную old_handler
mov eax,dword ptr es:[87h*4]
mov dword ptr old_handler,eax
; установить наш обработчик
pushf
cli
mov word ptr es:[87h*4], offset int_handler
mov word ptr es:[87h*4+2], seg int_handler
popf
; тело программы
[...]
; восстановить предыдущий обработчик
push 0
pop es
pushf
cli
mov eax,word ptr old_handler
mov word ptr es:[87h*4],eax
popf
Хотя прямое изменение
таблицы векторов прерываний и кажется
достаточно удобным, все-таки это не
лучший подход к установке обработчика
прерывания, и пользоваться им следует
только в случаях крайней
; скопировать адрес предыдущего обработчика в переменную old_handler
mov ax,3587h ; АН = 35h, AL = номер прерывания
int 21h ; функция DOS: считать
mov word ptr old_handler,bx ; возвратить
mov word ptr old_handler+2,es ; и сегментный
; установить наш обработчик
mov ax,2587h ; АН = 25h, AL = номер прерывания
mov dx,seg int_handler ; сегментный адрес
mov ds,dx ; в DS
mov dx,offset int_handler ; смещение в DX
int 21h ; функция DOS: установить
; (не забывайте, что ES изменился после вызова функции 35h!)
[...]
; восстановить предыдущий обработчик
lds dx,old_handler ; сегментный адрес в DS и смещение в DX
mov ax,2587h ; АН = 25h, AL = номер прерывания
int 21h ; установить обработчик
Обычно обработчики прерываний используют для того, чтобы обрабатывать прерывания от внешних устройств или чтобы обслуживать запросы других программ.
При помощи собственных
обработчиков исключений можно справиться
и с другими особыми
#DE (деление на ноль) — INT 0 — ошибка, возникающая при переполнении и делении на ноль. Как для любой ошибки, адрес возврата указывает на ошибочную команду.
#DB (прерывание трассировки) — INT 1 — ловушка, возникающая после выполнения каждой команды, если флаг TF установлен в 1. Используется отладчиками, действующими в реальном режиме.
#OF (переполнение) — INT 4 — ловушка, возникающая после выполнения команды INTO, если флаг OF установлен.
#ВС (переполнение при BOUND) — INT 5 — ошибка, возникающая при выполнении команды BOUND.
#UD (недопустимая команда) — INT 6 — ошибка, возникающая при попытке выполнить команду, отсутствующую на данном процессоре.
#NM (сопроцессор отсутствует) — INT 7 — ошибка, возникающая при попытке выполнить команду FPU, если FPU отсутствует.
Прерывания от внешних устройств, или аппаратные прерывания — это то, что понимается под термином «прерывание». Внешние устройства (клавиатура, дисковод, таймер, звуковая карта и т.д.) подают сигнал, по которому процессор прерывает выполнение программы и передает управление на обработчик прерывания. Всего на персональных компьютерах используется 15 аппаратных прерываний, хотя теоретически возможности архитектуры позволяют довести их число до 64.
Рассмотрим их кратко в порядке убывания приоритетов (прерывание имеет более высокий приоритет, и это означает, что, пока не завершился его обработчик, прерывания с низкими приоритетами будут ждать своей очереди).