Программирование на языке ассемблера

Автор: Пользователь скрыл имя, 22 Октября 2012 в 18:24, курсовая работа

Описание работы

Ассемблером называется машинно-зависимый компилятор, преобразующий специальным образом составленные текстовые строки в машинные инструкции. Как и любой другой компилятор, ассемблер упрощает разработку программ за счет того, что предоставляет пользователю доступ к кодам машинных инструкций и операндам с помощью символьных имен.
Достоинство заключается в том, что, программируя на ассемблере, программист обычно выбирает последовательность машинных инструкций так, чтобы реализовать нужные вычисления с максимальной скоростью при минимальных затратах памяти. С другой стороны, программирование на уровне машинных инструкций – чрезвычайно хлопотное занятие и не может сравниться по скорости разработки с программированием на языках высокого уровня. В этом заключается главный недостаток ассемблера.

Работа содержит 1 файл

Курсовая работа-ассемблер.doc

— 83.50 Кб (Скачать)

IRQ0 (INT 8) — прерывание системного таймера. Это прерывание вызывается 18,2 раза в секунду. Стандартный обработчик этого прерывания вызывает INT 1Ch при каждом вызове, так что, если программе необходимо только регулярно получать управление, а не перепрограммировать таймер, рекомендуется использовать прерывание 1Ch.

IRQ1 (INT 9) — прерывание клавиатуры. Это прерывание вызывается при каждом нажатии и отпускании клавиши на клавиатуре. Стандартный обработчик этого прерывания выполняет довольно много функций, начиная с перезагрузки по Ctrl-Alt-Del и заканчивая помещением кода клавиши в буфер клавиатуры BIOS.

IRQ2 — к этому входу на первом контроллере прерываний подключены аппаратные прерывания IRQ8 – IRQ15, но многие BIOS перенаправляют IRQ9 на INT 0Ah.

IRQ8 (INT 70h) — прерывание часов реального времени. Это прерывание вызывается часами реального времени при срабатывании будильника и если они установлены на генерацию периодического прерывания (в последнем случае IRQ8 вызывается 1024 раза в секунду).

IRQ9 (INT 0Ah или INT 71h) — прерывание обратного хода луча. Вызывается некоторыми видеоадаптерами при обратном ходе луча. Часто используется дополнительными устройствами (например, звуковыми картами, SCSI-адаптерами и т.д.).

IRQ10 (INT 72h) — используется дополнительными устройствами.

IRQ11 (INT 73h) — используется дополнительными устройствами.

IRQ12 (INT 74h) — мышь на системах PS используется дополнительными устройствами.

IRQ13 (INT 02h или INT 75h) — ошибка математического сопроцессора. По умолчанию это прерывание отключено как на FPU, так и на контроллере прерываний.

IRQ14 (INT 76h) — прерывание первого IDE-контроллера «операция завершена».

IRQ15 (INT 77h) — прерывание второго IDE-контроллера «операция завершена».

IRQ3 (INT 0Bh) — прерывание последовательного порта COM2 вызывается, если порт COM2 получил данные.

IRQ4 (INT 0Ch) — прерывание последовательного порта СОМ1 вызывается, если порт СОМ1 получил данные.

IRQ5 (INT 0Dh) — прерывание LPT2 используется дополнительными устройствами.

IRQ6 (INT 0Eh) — прерывание дисковода «операция завершена».

IRQ7 (INT 0Fh) — прерывание LPT1 используется дополнительными устройствами.

Самые полезные для программ аппаратные прерывания — прерывания системного таймера и клавиатуры. Так как их стандартные обработчики выполняют множество функций, от которых зависит работа системы, их нельзя заменять полностью. Следует обязательно вызвать предыдущий обработчик, передав ему управление следующим образом (Например, если его адрес сохранен в переменной old_handler):

                pushf

                call     old_handler

Эти две команды выполняют  действие, аналогичное команде INT (сохранить флаги в стеке и передать управление подобно команде call), так что, когда обработчик завершится командой IRET, управление вернется в нашу программу. Так удобно вызывать предыдущий обработчик в начале собственного. Другой способ — простая команда jmp:

                jmp      cs:old_handler

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

 

Практическая часть. Разработка алгоритма программы.

Перепрограммирование прерывания клавиатуры

 

   Когда  микропроцессор  клавиатуры помещает скан-код  в  порт  A микросхемы 8255 (адрес  порта  60Н   ), то при этом вызывается прерывание 9.  Задача этого прерывания  преобразовать скан-код символа, основываясь на состоянии клавиш-переключателей, и поместить его в буфер клавиатуры.  (Если скан-код соответствует клавише-переключателю, то в  буфер  клавиатуры не пишется ничего, за  исключением случая клавиши Ins, а вместо  этого  прерывание изменяет  байты  статуса,  расположенные  в  области  данных BIOS).   Прерывания  "ввода с клавиатуры" DOS и BIOS на  самом деле всего лишь прерывания "ввода из буфера клавиатуры". На самом деле они не распознают нажатия клавиш. Точнее, они читают интерпретацию введенных клавиш, которую  обеспечило прерывание 9. 

В прерывании клавиатуры можно выделить три основных шага:

   1.  Прочитать  скан-код и послать клавиатуре подтверждающий сигнал.

   2. Преобразовать скан-код в номер кода или в установку регистра статуса клавиш-переключателей.

   3. Поместить  код клавиши в буфер клавиатуры.

   В  момент вызова  прерывания скан-код будет находиться  в  порте A.  Поэтому сначала надо этот код прочитать и сохранить на стеке. Затем используется порт B (адрес 61Н),  чтобы быстро послать сигнал подтверждения микропроцессору клавиатуры. Надо просто установить бит 7 в 1, а затем сразу  изменить  его  назад в 0. Заметим, что бит 6 порта B управляет сигналом часов клавиатуры.  Он всегда должен быть установлен в 1, иначе клавиатура будет выключена. Эти адреса  портов  применимы и к AT, хотя он и не  имеет  микросхемы интерфейса с периферией 8255.

   Сначала скан-код  анализируется на предмет того, была ли клавиша нажата (код нажатия) или отпущена (код освобождения).  На всех машинах, кроме AT, код освобождения  индицируется установкой бита 7  скан-кода  в 1.  Для AT, у которого бит 7 всегда равен 0,  код освобождения состоит  из  двух  байтов:  сначала  0F0Н,  а  затем скан-код.  Все коды освобождения отбрасываются, кроме случая клавиш-переключателей. С другой стороны, все коды нажатия обрабатываются.

   После  того  как введенный символ  идентифицирован,  процедура ввода с клавиатуры должна найти соответствующий ему код ASCII или расширенный код.  В общем случае  скан-коды  сопоставляются элементам таблицы данных, которая анализируется инструкцией XLAT. XLAT принимает в AL число от 0 до 255, а возвращает в AL  1-байтное значение из 256-байтной  таблицы, на которую указывает DS:BX.

   Наконец, номера  кодов должны быть помещены  в буфер клавиатуры.

Процедура должна сначала проверить, имеется ли в  буфере место для следующего  символа.  Этот буфер  устроен как циклическая очередь. Ячейка  памяти 0040:001A содержит указатель  на  голову буфера, а 0040:001C  указатель на  хвост.   Эти словные указатели дают смещение  в  области  данных BIOS (которая начинается  в сегменте 40Н) и находятся в диапазоне от 30 до  60.

Новые символы вставляются  в ячейки  буфера с более старшими адресами,  а  когда достигнута верхняя граница, то  следующий  символ переносится в нижний конец  буфера.  Когда буфер полон, то указатель хвоста на 2 меньше указателя на голову  кроме случая, когда указатель на голову равен  30  (начало  области буфера), а в этом случае буфер полон, когда указатель хвоста равен 60.

   Для  вставки  символа в буфер, надо поместить  его в позицию, на которую указывает хвост буфера и затем увеличить указатель хвоста на  2; если указатель хвоста был равен 60, то надо  изменить  его значение на 30.  

Перепрограммирование отдельных  клавиш.

    Под  перепрограммированием клавиши понимается способ заставить ее выдавать другой код.  Но к тому времени, когда программа получает  код нажатой клавиши, прерывание клавиатуры уже проинтерпретировало входящий скан-код и преобразовало  его в некоторый заранее  предопределенный код ASCII или расширенный код.  К  счастью, начиная с MS DOS версии 2.0,  система содержит средства перепрограммирования  клавиш.   Это средство действует только  если  ввод воспринимается через  функции  DOS  ввода  с клавиатуры  функции прерывания  BIOS  16Н продолжают интерпретировать нажатия  клавиш нормальным образом.

   Перепрограммирование  доступно за счет Esc последовательностей.  Короткая  строка,  которая начинается с символа Esc  (ASCII  27), предназначается для вывода на  "стандартное  устройство  вывода", т.е.  на терминал.  Но благодаря наличию кода Esc символы даже не достигают монитора.  Вместо  этого такая строка заставляет MS DOS по  другому  интерпретировать клавишу, указанную в  этой  строке. Каждое изменение  клавиши  требует  собственной  строки, при этом один  и тот же код может присваиваться какому  угодно  количеству клавиш.

   Общий  вид такой строки такой: 

27,'[66;98p'   ; данная строка меняет «Б» на «б»

она начинается с кода Esc (ASCII 27),  за которым идет [, затем номер кода переопределяемой клавиши, затем точка с запятой (;), затем новый номер кода, присваиваемый   клавише  и,  наконец,  символ p.  

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

27,'[0;68;0;83p' ; переопределяет F10 (0;68) -> Delete (0;83)

Esc последовательности  ничего  более, чем строки, в которых  первый код или символ указывает какую клавишу нужно  переопределить, а оставшаяся часть строки  указывает какое значение Вы хотите ей придать.   Номера кодов должны быть всегда разделены точкой с запятой, а символы заключены в кавычки. Коды и символы могут быть перемешаны в любых сочетаниях.  Для того  чтобы такие переопределения клавиш были возможны, необходимо чтобы драйвер ANSI.SYS был загружен при загрузке операционной системы. В противном случае Esc последовательности будут игнорироваться.

Имеется  несколько вариантов допустимого вида строки.  Во-первых, символьные клавиши могут обозначаться самим символом, заключенным  в  кавычки. 

Таким образом, строка  27,'["Б";"б"p'  также меняет Б на б.

Во-вторых клавише  может быть присвоена целая строка  символов,  путем указания символов или их кодовых  номеров  в выражении. Строка  27,'["Б";"пробел Б"p' приведет к тому, что при нажатии на клавишу Б в верхнем регистре, будет печататься строчка - пробел Б.

На  самом деле эти  Esc последовательности  ничего более, чем строки, в которых первый код или символ указывает какую клавишу нужно  переопределить, а оставшаяся часть строки  указывает какое значение Вы хотите ей придать.  Коды и символы могут быть перемешаны в любых сочетаниях.  Для того  чтобы такие переопределения клавиш были возможны, необходимо чтобы драйвер ANSI.SYS был загружен при загрузке операционной системы. В  противном случае Esc последовательности будут игнорироваться 

   Реализация программы на языке ассемблер.

Для решения поставленной задачи программный код будет иметь вид приведенный ниже. Используем функцию 9  прерывания  21Н для посылки строки на стандартное  устройство вывода.  DS:DX должны указывать на первый символ строки в памяти  и  строка  должна  завершаться символом $ (24Н).  Здесь клавиша «Б» переопределяется таким образом, чтобы она действовала как строка « Б» (символ пробел и символ заглавная Б).

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

CНANGE_КEY   DB   27,'["Б";" Б"p$'

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

   LEA  DX,CНANGE_КEY       ;DS:DX должны указывать на строку

   MOV  AН,9                ;номер функции

   INT  21Н                 ;переопределение клавиши

Текст программы:

 

NEW_КEYBOARD  PROC FAR         ;сохраняем все изменяемые

              PUSН AX          ;регистры

              PUSН BX          ;

              PUSН CX          ;

              PUSН DI          ;

              PUSН ES          ;

;получаем скан-код  и посылаем сигнал подтверждения

   IN   AL,60Н         ;получаем  скан-код из порта A

   MOV  AН,AL          ;помещаем копию в AН

   PUSН AX             ;сохраняем скан-код

   IN   AL,61Н         ;читаем  состояние порта B

   OR   AL,10000000B   ;устанавливаем бит  7

   OUT  61Н,AL         ;посылаем измененный байт в  порт

   AND  AL,01111111B   ;сбрасываем бит 7

   OUT  61Н,AL         ;возвращаем состояние порта B

;ES должен указывать  на область данных BIOS

   MOV  AX,40Н         ;устанавливаем сегмент

   MOV  ES,AX          ;

   POP  AX             ;возвращаем скан-код из стека

; установить  наш обработчик

CНANGE_КEY   DB   27,'["Б";" Б"p$'

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

   LEA  DX,CНANGE_КEY       ;DS:DX должны указывать на строку

   MOV  AН,9                ;номер функции

   INT  21Н                 ;переопределение клавиши

:        POP  ES            ;восстанавливаем изменяемые

             POP DI            ;регистры

             POP  CX            ;

             POP  BX            ;

             POP  AX            ;

             MOV  AL,20Н        ;выдаем сигнал об окончании

             OUT  20Н,AL        ;аппаратного  прерывания

             IRET               ;возврат из прерывания

NEW_КEYBOARD ENDP

 

Вывод

Выполнив данную курсовую работу, я познакомился с программированием на языке ассемблера во всей широте его проявлений — от создания простых программ и процедур, вызываемых из программ на других языках, до драйверов устройств и операционных систем. Теперь должно быть очевидно, что ассемблер не только не сдает свои позиции, но и не может их сдать — ассемблер неотъемлемо связан с компьютером, и всюду, как только мы опускаемся с уровня абстракций языков высокого уровня, рано или поздно встречаемся с ним. В то же время и абстракции, и сложные управляющие структуры, и структуры данных выражаются на языке ассемблера наиболее эффективно. Ассемблер настолько многогранен, что нет никакой возможности описать все. Методы защиты от копирования и противодействия отладчикам, строение различных файловых систем, программирование на уровне портов ввода-вывода.

Информация о работе Программирование на языке ассемблера