Рефераты. Системное программирование

o                  Максимальное значение физического адреса равно0ff fffh, то есть1 Мбайт, но, фактически, в реальном режиме микропроцессора адресуется на 64 Кбайт больше, что следует из следующего вычисления:

Ffff0 – максимальное значение сегментной части адреса, сдвинутое на 4 разряда влево;

+

0fffh – максимальное значение смещения;

10ffef – максимальный физический адрес в реальном режиме.

Этот пример говорит о том, что в модели микропроцессоров, начиная с i286, при определенных обстоятельствах возможна адресация оперативной памяти за пределами первого мегабайта. Это обстоятельство даже использовалось последними версиями MS-DOS для размещения служебных программ в этом дополнительном сегменте памяти. Формирование значений адреса сразу за первым мегабайтом возможно и в микропроцессоре i8088/86. в нем при появлении физического адреса большего 0ffffh, например 1 000 054h, микропроцессор отбрасывает 21-й единичный бит. Происходит так называемое «заворачивание» адреса, поэтому сформированный физический адрес на шине адреса будет равен 00054h. Для того чтобы обеспечить полную эмуляцию данной особенности микропроцессора i8088/86, в моделях микропроцессоров, начиная с i80286, была предусмотрена возможность блокировки адресной линии A20 (управление тем самым 21-м битом адреса). Для обеспечения доступа к адресам оперативной памяти, лежащим за пределами первого мегабайта, необходимо специальным образом открывать эту адресную линию;

o                  В реальном режиме схема распределения оперативной памяти – фиксированная. Перечислим расположение некоторых из системных областей, которые потребуются нам в дальнейшем:

·                    В диапазоне адресов 00000h – 003ffh (первый мегабайт оперативной памяти) находится таблица векторов прерываний (ТВП). Адрес программы прерывания наз. вектором. Она содержит 256 векторов прерываний размером 4 байта (указателей на программы обработки прерываний). В первом слове хранится значение ip, а во втором – cs. Младшие 1024 байт памяти содержат вектора прерываний, таким образом, имеется место для 256 векторов;

·                    В диапазоне адресов 00400h – 006ffh сразу за таблицей векторов прерываний располагается область памяти, содержащая жестко структурированные данные, обеспечивающие работу BIOS и MS-DOS;

·                    С адреса 0b8000h располагается область видеопамяти, в которой формируется изображение, которое мы видим на экране.

Общая схема обработки прерываний в реальном режиме

Обработка прерываний (как внешних, так и внутренних) в реальном режиме микропроцессора производится в три этапа:

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

2.                  Переход к выполнению и выполнение программы обработки прерываний.

3.                  Возврат управления прерванной программе.

Первый этап должен обеспечить временное прекращение выполнения текущей программы таким образом, чтобы потом прерванная программа продолжила свою работу так, как будто никакого прерывания не было. Любая программа, загруженная для выполнения операционной системой, занимает свое, отдельное от других программ, место в оперативной памяти. Разделяемыми между программами ресурсами являются регистры микропроцессоров, в том числе регистр флагов, поэтому их содержимое нужно сохранять. Обязательным для сохранения являются регистры cs, ip и flags \ eflags, поэтому они при возникновении прерывания сохраняются микропроцессором автоматически. Пара cs:ip содержит адрес команды, с которой необходимо начать выполнение после возврата из программы обслуживания прерывания, а flags \ eflags – состояние флагов после выполнения последней команды прерванной программы в момент передачи управления программе обработки прерывания. Сохранение содержимого остальных регистров должно обеспечиваться программистом в начале программы обработки прерывания до их использования. Наиболее удобным методом хранения регистров является стек. В конце первого этапа микропроцессор после включения в стек регистров flags, cs, i сбрасывает бит флага прерываний IF в регистре flags (но при этом в стек записывается предыдущее содержимое регистра flags с еще установленным IF). Тем самым предотвращаются возможность возникновения вложенных прерываний по входу INTR и порча регистров исходной программы вследствие неконтролируемых действий со стороны программы обработки вложенного прерывания. После того как необходимые действия по сохранению контекста завершены, обработчик аппаратного прерывания может разрешить вложенные прерывания командой sti.

Набор действий по реализации второго этапа заключается в определении источника прерывания и вызова соответствующей программы обработки. В реальном режиме микропроцессора допускается от 0 до 255 источников прерываний. Количество источников прерываний ограничено размером таблицы векторов прерываний. Эта таблица выступает связывающим звеном между источником прерывания и процедурой обработки. Данная таблица располагается в памяти, начиная с адреса 0. каждый элемент таблицы векторов прерываний занимает 4 байта и имеет следующую структуру:

o                  1-е слово элемента таблицы – значение смещения начала процедуры обработки прерывания (n) от начала кодового сегмента;

o                  2-е слово элемента таблицы – значение базового адреса сегмента, в котором находится процедура обработки прерывания.

Определить адрес, по которому находится вектор прерывания с номером n, можно следующим образом:

cмещение_элемента_таблицы_векторов_прерываний = n*4

Теперь понятно, что на втором этапе обработки прерывания микропроцессор выполняет следующие действия:

1.                  По номеру источника прерывания путем умножения на 4 определяет смещение в таблице векторов прерываний.

2.                  Помещает первые два байта по вычисленному адресу в регистр ip.

3.                  Помещает вторые два байта по вычисленному адресу в регистр cs.

4.                  Передает управление по адресу, определяемому парой cs:ip.

Далее выполняется сама программа обработки прерывания. Она, в свою очередь, также может быть прервана, например, поступлением запроса от более приоритетного источника. В этом случае этапы 1 и 2 будут повторены для вновь поступившего запроса.

Набор действий по реализации этапа 3 заключается в восстановлении контекста прерванной программы. Так же, как и на этапе 1, на данном последнем этапе есть действия, выполняемые микропроцессором автоматически, и действия, задеваемые программистом. Основная задача на этапе 3 – привести стек в состояние, в котором он был сразу после передачи управления данной процедуре. Для этого программист указывает необходимые действия по восстановлению регистров и очистке стека. Этот участок кода необходимо защитить от возможности искажения содержимого регистров (в результате появления аппаратного прерывания) с помощью команды cli. Последние команды в процедуре обработки прерывания – sti и iret, при обработке которых микропроцессор выполняет следующие действия:

1)                 sti – разрешить аппаратные прерывания по входу INTR;

2)                 iret – извлечь последовательно три слова из стека и поместить их, соответственно, в регистры ip, cs, flags.

В результате этапа 3 управление возвращается очередной команде прерванной программы, которая должна была выполнится, если бы прерывания не было.

Аппаратные прерывания могут быть инициированы программно командой микропроцессора int n, где n – номер аппаратного прерывания в соответствие с таблицей векторов прерываний. При этом микропроцессор также сбрасывает флаг IF, но не вырабатывает сигнал INTA.

Написание собственного прерывания


Имеется несколько причин для написания собственного прерывания. Во-первых, большинство из готовых прерываний, обеспечиваемых операционной системе, ничто иное, как обычные процедуры, доступные для всех программ, поэтому можно добавить что-то свое. Например, многие программы могут использовать процедуру, выводящую строки на экран вертикально. Вместо того, чтобы включать ее в каждую программу в качестве процедуры можно установить ее как прерывание, написав программу, которая останется резидентной в памяти после завершения. Тогда, например, можно использовать int 80h вместо WRITE_VERTICALLY (вызов прерывания несколько медленней, чем вызов процедуры).

Второй причиной написания прерывания может быть использование какого-либо отдельного аппаратного прерывания. Это прерывание автоматически вызывается при возникновении определенных условий. В некоторых случаях BIOS инициализирует вектор этого прерывания так, что он указывает на процедуру, которая вообще ничего не делает (она содержит только iret). Можно написать свою процедуру и изменить вектор прерываний, чтобы он указывал на нее. Тогда при возникновении аппаратного прерывания будет выполняться нами написанная процедура. Одна из таких процедур это прерывание времени суток, которое автоматически вызывается 18,2 раза в секунду. Обычно это прерывание только обновляет показания часов, но можно изменить его код как угодно программисту.

И, наконец, возникает иногда желание написать прерывание, которое полностью заменит одну из процедур ОС, приспособленное к программным нуждам.

Рассмотрим пример разработки прерывания в общем случае.

Функция 25h прерывания 21h устанавливает вектор прерывания на указанный адрес cs:ip. Чтобы установить вектор, указывающий на одну из ваших процедур, нужно поместить сегмент процедуры в ds, а смещение в dx. Затем нужно поместить номер прерывания в al и вызвать функцию. Любая процедура прерывания должна завершаться не обычной инструкцией RET, а IRET (IRET выталкивает из стека три слова, включая регистр флагов, в то время как RET помещает на стек только два, если вы попытаетесь тестировать такую процедуру как обычную процедуру, но кончающуюся IRET, то Вы исчерпаете стек.). Отметим, что функция 25H автоматически запрещает аппаратные прерывания в процессе изменения вектора, поэтому не существует опасности, что посреди дороги произойдет аппаратное прерывание, использующее данный вектор.

 Когда программа завершается, должны быть восстановлены оригинальные вектора прерываний. В противном случае последующая программа может вызвать данное прерывание и передать управление на то место в памяти, в котором Вашей процедуры уже нет. Функция 35 прерывания 21H возвращает текущее значение вектора прерывания, помещая значение сегмента в ES, а смещение в BX. Перед установкой своего прерывания получите текущее значение вектора, используя эту функцию, сохраните эти значения, и затем восстановите их с помощью функции 25H (как выше) перед завершением своей программы.

Например:


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

 KEEP_CS DW 0 ;хранит сегмент заменяемого прерывания

 KEEP_IP DW 0 ;хранит смещение прерывания

;---в начале программы

 MOV AH,25H ;функция получения вектора

 MOV AL,1CH ;номер вектора

 INT 21H ;теперь сегмент в ES, смещение в BX

 MOV KEEP_IP,BX ;запоминаем смещение

 MOV KEEP_CS,ES ;запоминаем сегмент

; ---в конце программы

 CLI

 PUSH DS ;DS будет разрушен

 MOV DX,KEEP_IP ;подготовка к восстановлению

 MOV AX,KEEP_CS ;

 MOV DS,AX ;подготовка к восстановлению

 MOV AH,25H ;функция установки вектора

 MOV AL,1CH ;номер вектора

 INT 21H ;восстанавливаем вектор

 POP DS ;восстанавливаем DS

 STI

Имеется пара ловушек, которых следует избегать при написании прерывания. Если новая процедура прерывания должна иметь доступ к данным, то необходимо позаботиться, чтобы DS был правильно установлен (обычно прерывание может использовать стек вызывающей программы). Другая неприятность может заключаться в том, что при завершении программы по Ctrl-Break вектор прерывания не будет восстановлен, если только Вы не предусмотрите, чтобы программа реакции на Ctrl-Break выполняла эту процедуру.

Список используемой литературы:

 

1)                «Assembler. Учебник» В.Юров, изд. «Питер», 2000г

2)                «Ассемблер и программирование для IBM PC» Питер Абель, изд. технологический институт «Британская Колумбия»


Страницы: 1, 2, 3



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.