Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Textnew2

.pdf
Скачиваний:
13
Добавлен:
06.02.2018
Размер:
1.48 Mб
Скачать

ходимым для элементарного понимания, отсылая за подробностями к специальной литературе [12,21].

Основные действия по управлению КНП осуществляются, как правило, однократно при запуске операционной системы. Их целью состоит задание номеров прерываний, которые КНП будут посылать в процессор при возникновении сигнала запроса прерывания на входе контроллера. Каждый из рассматриваемых логических контроллеров имеет 8 входов, но программирование задает номер прерывания только для первого из них, номера прерываний для следующих входов формируются КНП автоматически как следующие за первым.

Для старой ОС MS-DOS (и начальной фазы загрузки самых современных компьютеров типа IBM) начальными номерами прерываний для главного КНП оказывается номер 09h, а для вспомогательного КНП - номер 70h. Логические входы этих контроллеров принято обозначать как IRQномер, входы IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 относятся к главному КНП, входы IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15 - к вспомогательному. Причем эти контроллеры соединены так, что приоритеты входов располагаются в последовательности IRQ0 > IRQ1 > IRQ2 = IRQ8 > IRQ9 > IRQ10 > IRQ11 > IRQ12 > IRQ13 > IRQ14 > IRQ15 > IRQ3 > IRQ4 > IRQ5 > IRQ6 > IRQ7. Наибольший приоритет имеет вход IRQ0. Система приоритетов важна для функционирования, потому что возможно одновременное возникновение сигналов запроса прерываний на двух (и более входах) системы КНП. При таком возникновении КНП обеспечивает реакцию только на более приоритетный сигнал, а другой (другие) запоминаются на внутреннем регистре контроллера. Если при обработке сигнала запроса, запомненного в КНП, приходит другой сигнал, то он просто запоминается на входном регистре (до тех пор пока ему не будет позволено влиять на дальнейшие цепи аппаратуры).

Косвенным последствием такой организации аппаратной системы является необходимость явного указания контроллеру, что программная реакция на сигнал прерывания, дошедший до процессора, осуществлена и аппаратура может сбросить этот сигнал внутри контроллера и далее реагировать на другие запомненные на входе сигналы, в частности на менее приоритетные сигналы. Такое указание КНП на завершение аппаратно-программной части обработки сигнала выполняется специализированной двоичной командой для КНП, обозначаемой как End Of Interrupt (сокращенно EOI). Указанное обозначение не распознается никаким ассемблером, так как это команда не для процессора, а для специализированного контроллера. Ее числовое значение есть 20h. Команду эту следует посылать в базовый порт КНП. Таким образом, указание EOI в главный КНП выполняется двумя командами

mov al, 20h out 20h, al

Для соответствующего указания вспомогательному КНП следует во второй из этих команд вместо номера порта 20h использовать 0A0h.

Заметим, что в старой ОС MS-DOS (и в начальной фазе загрузки самых современных компьютеров типа IBM) на вход IRQ0 поступают сигналы от таймера, а на вход IRQ1 - сигналы от клавиатуры. Современные многофункциональные аппарат-

141

ные средства позволяют переключить (переназначить) аппаратные сигналы на входы КНП по желанию разработчиков ОС и конечных пользователей (эти возможности рассматриваться не будут). Таким образом, в перечисленных простейших случаях сигнал от таймера будет вызывать прерывание с номером 08h, а сигнал от клавиатуры будет вызывать прерывание с номером 09h. (Заметим, что маскирование сигнала от таймера требует установки в единицу самого младшего бита порта 21h.)

Теперь у нас есть почти весь необходимый материал для простейший программы, иллюстрирующей ввод по прерыванием. Остается только узнать, в каком порту оказывается информация от клавиатуры при возникновении прерывания с номером 09h. Оказывается, что для этих целей предназначен порт с номером 60h. Следует обратить еще раз пристальное внимание, что правильная информации о вводе с клавиатуры в этом порту находится только после возникновения прерывания по номеру, отвечающему сигналу от клавиатуры.

В современной аппаратуре чтение из порта 60h, выполняющееся на уровне электронных сигналов как отдельное четко различимое действие, порождает для клавиатуры сигнал, что данные взяты и можно устанавливать в этом порту следующие данные. (Таким образом, повторное чтение из порта 60h программой обработчика в общем случае может дать другой результат.)

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

Современная клавиатура функционирует таким образом, что посылает специальный код данных на каждое нажатие и даже на каждое отпускание клавиши. Причем для возможности перенастройки клавиатуры на любой алфавит, в системный блок компьютера посылается так называемый скан-код (scan-code). В простейшем случае (для основных клавиш) скан-код представляет просто порядковый номер клавиши. Так клавиша Esc имеет скан-код, равный 01, клавиша с символом '1' имеет сканкод, равный 02, клавиша с символом '2' - скан-код, равный 03 и т.д. Первая дополнительная особенность заключается в том, что скан-код отпускания для основных клавиш формируется из кода нажатия "дописыванием" старшего бита (так что сканкод отпускания клавиши '1' есть 82h). Это позволяет единообразно распознавать коды нажатия и отпускания для основных клавиш. Для дополнительных клавиш (клавиш позиционирования курсора и т.д.) могут использоваться не один скан-код на нажатие, а несколько.

Рассмотрим простую программу, предназначенную для запуска из под функционирующей ОС MS-DOS и приведенную на рис. 7.3.1.

org 100H SEGMENT .text

start: jmp setisr ; procedure isro9h

142

isr09h:

push ax

in al,60h

; в AL скан-код

cmp al,57h

; F11 ?

je ca

 

 

cmp al,58h

; F12 ?

jne next

 

ca: call beep

 

next: pop ax

 

mov al, 20h

 

out 20h, al

 

iret

 

 

; end procedure isr09h beep: pusha

mov dl, 7 mov ah,2 int 21h popa

ret

setisr: push es ; store segment address of Our Program mov ax, 0

mov es, ax ; ES = базовый адрес Interrupt Vectors Table cli

mov dx, isr09h pop bx

mov [es:4*09h], dx mov [es:4*09h+2], bx sti

circ: jmp circ ; зацикливание текущего процесса или в MS-DOS вместо этого

;можно выполнить следующие две команды

;mov dx, setisr

;int 27h ; TSR COM-программу

Рис. 7.3.1. Обработчик прерываний от клавиатуры для MS-DOS

Эта программа представляет собой программу очень примитивного обработчика сигналов от нажатий на клавиши клавиатуры. Аналогично рассмотренной ранее программе на рис. 8.2.1, данная программа состоит из собственно обработчика с внутрипрограммным именем isr09h и инициализирующей части с начальной меткой setisr. Инициализирующая часть ничем не отличается от рассмотренной ранее, кроме номера прерывания, для которого устанавливается обработчик. В данном случае это номер 09h, соответствующий клавиатуры в указанных выше условиях. Собственно обработчик читает данные из порта 60h, получая таким образом скан-

143

код. Далее используется, что скан-коды клавиш F11 и F12 есть, соответственно, 57h и 58h.

7.4. Обработка прерываний внесистемной программой реального режима

Рассмотренные примеры базировались на операционной системе MS-DOS, которая давно уже не поддерживается своим создателем. В качестве полумеры, функциональные возможности этой ОС были включены в операционные системы семейства Windows 9x, причем когда такое моделирование оказывалось недостаточным, то в указанных ОС можно было выполнять перезагрузку в режиме эмуляции MS-DOS. До недавнего времени все это обеспечивало выполнение любых программ, разработанных для исходной ОС реального режима фирмы Microsoft. Но переход к более поздним ОС семейства Windows NT, в частности к Windows 2000 и XP, отсекает такие возможности. Последние универсальные ОС не работают в реальном режиме, даже моделируемом. Поэтому изучать системные средства архитектуры на работающих программных примерах с помощью указанных ОС оказывается невозможным. С другой стороны, отказ от практического изучения системных средств архитектуры может дать только снижение квалификационного уровня будущих специалистов по информатике.

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

Как обычные ОС, так и внесистемные программы используют встроенные в компьютер средства начальной загрузки (Initial Program Load). Эти средства в современных компьютерах образуются совокупностью программ, постоянно присутствующих в составе постоянных запоминающих устройств компьютера, и программой загрузочного сектора системного устройства хранения информации. В качестве последнего устройства чаще всего используется раздел жесткого диска или дискета.

Чтобы не отвлекаться на проблемы организации загрузочного сектора, в ближайшем рассмотрении будем опираться на системные (загрузочные) дискеты операционной системы OS/2. (В дальнейшем покажем, как создать аналог такой дискеты.) Системная дискета указанной ОС автоматически загружает находящийся на ней файл с именем OS2BOOT. Причем на таких дискетах используется обычная файловая система FAT16, позволяющая записывать на дискету файлы практически в любой известной обучаемым операционной системе. Из этого вытекает возможность разработки демонстрационных и экспериментальных программ с помощью транслятора NASMW в операционных системах производства фирмы Microsoft. Причем с формированием результата как бинарного файла и записью результата в загрузочный сектор подготовленной ранее дискеты.

144

Сама подобная дискета не будет ничем заметным обличаться от обычных форматированных дискет, за исключением особого содержимого загрузочного сектора. Такую дискету можно получить, полностью скопировав инсталляционную дискету системы OS/2 и удалив из нее все ненужные теперь файлы (загрузочный сектор менять не надо!). Другой более простой и, для большинства более доступный, способ создания такой дискеты будет изложен в разделе 8.7.

Единственное ограничение при использовании такой дискеты, с целью автоматической загрузки файла OS2BOOT, заключается в том, что данные этого файла должны быть записаны в последовательно размещаемых кластерах. (Если читатель еще не знаком с проблемами размещения файлов в файловых системах типа FAT, то достаточно записывать новую версию разрабатываемого файла OS2BOOT на такую дискету, с которой перед этих удалены другие файлы. Другим вариантом действий, гарантирующих требуемое условие, является предварительное стирание лишь старой версии файла и, затем, выполнение дефрагментации этой дискеты с помощью системного сервиса ОС Windows. Проще всего, если на этой дискете присутствует только файл OS2BOOT - тогда ни о каких дополнительных действиях заботится не надо.

Само содержимое файла OS2BOOT оказывается полностью в нашем дальнейшем распоряжении. Машинные коды программы OS2BOOT будут помещаться в оперативную память при загрузке с этой дискеты. (Для такой загрузки может потребоваться настройка в Setup BIOS используемого компьютера, так как в современных компьютерах часто устанавливают режим загрузки только с жесткого диска.) После загрузки такой программы в память, управление будет передано на начальный байт этой программы. Заметим, что в программе загрузочного сектора приняты меры для нормального функционирования стека. Подробней на этом остановимся при обсуждении более сложных режимов чем реальный режим.

Двоичные коды программы OS2BOOT будут помещаться, начиная с физического адреса 8000h оперативной памяти (начиная с границы 32 Кбайта от начала памяти). Заметим, что эта величина начального адреса обусловлена программой загрузочного сектора и, используя материал из 7.7, ее можно изменить.

Для простейшего использования описанных возможностей рассмотрим программу, приведенную на рис. 7.4.1.

SEGBASE EQU 800h segment .text

_start:cli push cs pop ds

mov ax,0 mov es, ax

mov WORD [es:4*05h], interp

mov WORD [es:4*05h+2], SEGBASE mov WORD [es:4*09h], interp9

145

mov WORD [es:4*09h+2], SEGBASE mov ax, 0B800h

mov es,ax

wiwod: mov cx, lenmsg ; вывод сообщения о RLMODE

mov di, 800

 

mov si, msg

 

call wiwtxt

 

int 5 ; обращаемся к обработчику прерывания с номером 5

mov al,11111101b ; разрешаем маской аппаратные прерывания

out 21h,al

; только для клавиатуры

sti

 

dalee: jmp dalee

;----- end main program

wiwtxt: ; процедура вывода на экран

 

pusha

 

 

cld

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

 

mov al,[attr] ; атрибут для вывода текста

rr:

movsb ; пересылка байта из сообщ. на экран, инкр.SI и DI

 

stosb

; пересылка байта атрибута на экран, инкр. DI

 

loop rr

; повторять по числу символов в тексте

 

popa

 

 

ret

;;wiwtxt endp

interp9: ; обработчик прерываний с номером 9

 

pusha

 

 

in al, 60h

; читаем скан-код из порта 60h

 

test al,80h

; проверяем не сигнал ли это отпущения клавиши

 

jnz dal

 

 

mov cx, lenmsg9

 

mov di, [posi]

 

mov si, msgint9

 

call wiwtxt

; вывод сообщения MSGINT9 о нажатии клавиши

add WORD [posi], 30

; подготовить номер позиции экрана для след. сообщ.

cmp WORD [posi], 4000-30; если вышли за пределы экрана - jl dal

mov WORD [posi],0 ; то с его начала

; завершение обработчика аппаратного прерывания от клавиши

dal: mov al,20h

; кодом команды End_Of_Interrupt = 20h

out 20h,al

; сбросить обработанный сигнал в КНП

popa

iret ;; endp interp9

146

interp: ; proc near ; процедура для вывода на экран сообщения

 

pusha

 

 

 

mov cx, lenmsgp ; о прерывании

 

mov di, 3200

 

mov si, msgintp

 

call wiwtxt

 

 

popa

 

 

 

iret ; interp

endp

; конец сегмента команд

;;data segment

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

attr

db 1eh

; байта атрибутов: ярко-желтый на синем фоне

posi

dw 1920

; позиция, с которой вывод о нажатии клавиши

msg

db 'We are into real mode!'

lenmsg equ $-msg ; длина сообщения msg

msgintp

db 'Interrupt is in Real mode!'

lenmsgp equ $-msgintp

msgint9

db 'Pressed key! '

lenmsg9 equ $-msgint9

Рис. 7.4.1. Внесистемная обработка прерываний от клавиатуры

вреальном режиме

Вначале данной программы размещены команды действий по установке обработчика прерываний с номером 09h. Этот обработчик находится в составе рассматриваемой программе и имеет в исходном тексте программы начальную метку interp9.

Заметим, что в качестве сегментного адреса данного обработчика использована константа, заданная символическим обозначением SEGBASE и отвечающая начальному адресу данной программы 08000h, когда она загружается указанной выше программой загрузочного сектора.

В начале нашей программы выполняется установка содержимого сегментного регистра DS так, чтобы оно совпадало с содержимым сегментного регистра CS. (При использовании загрузчика односегментных программ из MS-DOS эти действия незаметно для пользователя всегда выполнял загрузчик операционной системы.) В нашем случае загрузчик из загрузочного сектора дискеты значительно более специализирован и примитивен. Он только переносит с дискеты содержимое файла OS2BOOT в оперативную память, начиная с ее фиксированного адреса, и передает управление по нулевому смещению в этой программе. Никаких других настроек при этом не производится. Перенос содержимого CS в DS осуществляется с помощью стека. (Более того, с регистром CS невозможно непосредственно выполнить никакое действие командой, кроме запоминание его содержимого в стеке!)

Далее сегментный регистр ES устанавливается так, чтобы указывать на сегмент, начинающийся с нулевого адреса оперативной памяти (для доступа к таблице векторов прерываний). Для номеров прерываний 05 и 09 в их векторы командами

147

MOV заносятся начальные адреса обработчиков прерываний с исходными именами interp и interp9. Заметим, что все манипуляции с таблицей векторов прерываний выполняются при запрещенных командой CLI аппаратных прерываниях. В регистр ES затем заносится сегментный адрес области видеопамяти.

Для вывода текстовой информации в рассматриваемой программе служит подпрограмма с именем wiwtxt. Используя предварительно установленную в регистрах SI, DI и CX информацию, она выводит на экран текст, применяя в качестве атрибутов значение области attr. Этот вывод использует строковые команды movsb и stosb, причем первая из них пересылает по байтам содержимое текста, а вторая в очередной байт помещает значение атрибута из регистра AL. Регистр CX при входе в процедуру задает число выводимых символов, регистр SI передает смещение начала текста в сегменте данных, а регистр DI задает начальную позицию в видеопамяти, с которой формируется вывод.

Эта процедура используется в главной части нашей программы для информирования пользователя о начале ее функционирования. С этой целью в ее участке, начиная с метки wiwod, в регистры SI, DI и CX заносится информация, необходимая для вывода текста сообщения msg, размещаемого с начала 5-й строки экрана (со смещения 160*5 видеопамяти).

Далее с помощью команды программного прерывания INT 5 вызывается обработчик прерывания interp. Его действия заключаются в выводе сообщения о вызове обработчика, которое отображается в 20-й строке экрана текстом из области msgintp.

Затем в главной части программы производится принудительная установка маски главного КНП. Маска теперь разрешает прохождение через контроллер только сигналов от клавиатуры и запрещает все другие сигналы запросов прерывания. Выполняется команда STI, открывая тем самым вход процессора для сигналов прерывания. После этого главная программа входит в бесконечный цикл командой "dalee: jmp dalee".

Теперь каждое нажатие на клавишу клавиатуры вызывает обработчик прерывания 09, который в программе представлен процедурой interp9. В обработчике читается содержимое порта 60h и проверяется, не установлен ли в прочитанном значении старший бит. Если он установлен (скан-код отпускания клавиши), то участок процедуры для вывода сообщения обходится. Сообщение с текстом в области msgint9 выводится каждый раз в новой позиции экрана, задаваемом значением поля posi с помощью процедуры wiwtxt. Значение поля posi после вывода корректируется, причем делается проверка, не перейдет ли следующий вывод сообщения за пределы экрана. В случае определения такой ситуации значение в posi устанавливается на начальную позицию области видеопамяти экрана. Перед выходом из обработчика в базовый порт КНП посылается команда EOI для сброса контроллера, чтобы он был способен реагировать на следующий запрос от клавиатуры.

Если программа, приведенная на рис. 7.4.1, названа iplreal.asm, то формирование нужного загружаемого файла на специально подготовленной дискете (что обсуждалось выше) может быть осуществлено командной последовательностью

148

nasmw -f bin -o OS2BOOT iplreal.asm -l iplreal.lst copy OS2BOOT a:

После такой подготовки следует перегрузить компьютер, сохраняя в приводе дискету с записанной программой. После проверки функционирования разработанной программы, к сожалению, компьютер придется опять перегрузить - удалив дискету из привода - для доступа к полноценной операционной системе.

7.5. Построение программ защищенного режима

Современные процессоры используют не реальный режим для доступа к ячейкам памяти, а так называемый защищенный режим. Защищенный режим возник в свое время для защиты одновременно выполняющихся программ друг от друга. Дело в том, что эффективное использование вычислительной техники требует одновременного нахождения в оперативной памяти не одной, а многих программ. Тогда переключение процессора на выполнение другой программы требует лишь малого времени и операционная система может обеспечить видимость одновременного выполнения многих программ на одном процессоре. Последнее, в свою очередь, вызывается запросами современных пользователей, привыкших иметь одновременно функционирующими множество программ: кроме вычислительных программ иметь работающими еще и программы проигрывания аудиозаписей, программы межсетевого взаимодействия, в частности Internet, игровые и т.п. Функционирование же множества программ, одновременно размещенных в памяти, к сожалению, нередко приводит к обращениям в области данных, программе не принадлежащих. Эти обращения своими причинами имеют ошибки в программе, но принципиальной проблемой является невозможность устранения таких ошибок для любой сколько-нибудь сложной программы.

Технические аспекты, возникающие при таких ошибочных взаимодействиях, были хорошо изучены практически еще в 60-х годах XX века и единственным решением оказалось введение специальных аппаратно-программных средств, препятствующих таких взаимодействиям. (Заставить кого-то писать безошибочные программы нет никакой возможности.) Оперативное использование этих средств и получило название защищенного режима.

Какой из режимов - реальный или защищенный использует процессор в текущий момент определяется в Intel процессорах младшим битом специального управляющего регистра, имеющего обозначение CR0. Единичное значение этого бита задает именно защищенный режим. Но для функционирования защищенного режима установки этого бита недостаточно. Совершенно необходимо включение в использование специальной системной таблицы, которая называется глобальная таблица дескрипторов памяти, или сокращенно, GDT (Global Descriptor Table). Включение в использование представляет собой занесение адреса таблицы GDT и размера этой таблицы еще в один специальный регистр, называемый GDTR. (Точнее вместо размера следует занести максимальное смещение байтов в этой таблице, т.е. ее размер минус единица.) Регистр GDTR 48-битный, причем адрес таблицы GDT должен за-

149

нимать в этом регистре старшие четыре байта. Занесение информации в этот регистр возможно только специальной командой, имеющей мнемонику LGTD, операндом которой должно быть 6-байтовая область данных в памяти.

Когда процессор работает в защищенном режиме, адреса начала разнотипных сегментов памяти содержатся не в сегментных регистрах, а в отдельных дескрипторах памяти, которые в простейшем случае размещаются в GDT. Сами же сегментные регистры используются в основном как индексы для таблицы дескрипторов памяти. Иначе говоря, биты сегментного регистра, кроме трех младших битов, задают номер соответствующего дескриптора памяти. Таким образом, DS содержит номер дескриптора памяти для текущего сегмента памяти, CS содержит номер дескриптора памяти для текущего сегмента машинных кодов, а SS - номер дескриптора памяти для стека, используемого в текущий момент.

Сами дескрипторы памяти имеют размер в восемь байтов, среди которых для задания базового адреса сегмента памяти предназначены 2-й, 3-й, 4-й и 7-й. (С точки зрения содержательной критики, структура этих дескрипторов более чем "не регулярна", иначе говоря, составлена очень своеобразно и достаточно неестественно. Причиной этому явилась история создания процессоров с защищенным режимом в фирме Intel, которые создавались постепенно и "по частям".) Младшие два байта дескриптора (0-й и 1-й), а также младшая половина 6-го байта в совокупности составляют так называемый limit - предельное допустимое смещение в сегменте. Пятый байт этих дескрипторов называется байтом прав доступа - Access Rights (сокращенно - AR). Практически этот пятый байт во всех дескрипторах служит в первую очередь для различения назначения дескриптора. В дескрипторах памяти он, в частности, задает разрешенные режимы доступа к байтам внутри сегмента памяти. Имеются целый ряд возможностей для режимов доступа. Сегмент может быть предназначен только для извлечения из него машинных команд, для машинных команд и констант, только для констант или же для записи и чтения из него данных.

Подробное описание строение дескрипторов памяти содержится во множестве доступных источников, например в [6,8,15]. С нашими ознакомительными целями достаточно считать, что для содержательно перечисленных выше прав доступа, исходное значение этого байта нужно задавать, соответственно, константами 98h, 9Ah, 90h и 92h. (Напомним, что мы рассматриваем только простейшие варианты использования защищенного режима.)

На рис. 7.5.1 приведена демонстрационная программ, использующая для своего содержательного функционирования защищенный режим. Практически в защищенном режиме она всего лишь выводит простое сообщение на экран, но позволяет обсудить общие особенности программ защищенного режима и особенно проблемы и приемы перехода от реального в защищенный режим. Заметим, что все - даже самые сложные процессоры Intel - после включения питания или аппаратного сброса начинают свое функционирование в реальном режиме, но никогда сразу в защищенном. Поэтому забота перевода их в защищенный режим ложится на программистов соответствующей квалификации.

150

Соседние файлы в предмете Операционные системы