Операционные системы
Методы обработки прерываний. Распределение оперативной памяти в Windows. Файловая система NTFS. Модель Холта для проблемы тупика. Разработка и реализация алгоритма. Защищенный режим работы процессора с точки зрения обработки прерываний. Прямой ввод-вывод.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | контрольная работа |
Язык | русский |
Дата добавления | 22.05.2012 |
Размер файла | 334,3 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
ГОУ ВПО «Московский государственный открытый университет»
Чебоксарский политехнический институт (филиал)
Кафедра информационных технологий и программирования
КОНТРОЛЬНАЯ РАБОТА
Операционные системы
Выполнил
студент 3 курса заочной формы обучения
шифр специальности 230105
учебный шифр 609563
Андронников Сергей Георгиевич
Проверил
Богомолов А.В
Чебоксары - 2010г.
СОДЕРЖАНИЕ
Часть 1. Методы обработки прерываний
Часть 2. Распределение оперативной памяти в Windows 95-98
Часть 3. Файловая система NTFS
Часть 4. Модель Холта для проблемы тупика. Разработка и реализация алгоритма
Часть 5.1 Прямой ввод-вывод
Часть 5.2 Защищенный режим работы процессора с точки зрения обработки прерываний
6. Литература
Часть 1. Методы обработки прерываний
Общие принципы.
Прерывания и исключения нарушают нормальный ход выполнения программы для обработки внешних событий или сообщения о возникновении особых условий или ошибок.
Аппаратные прерывания подразделяются на маскируемые и немаскируемые. Процессор может воспринимать прерывания после выполнения каждой команды, длинные строковые команды имеют для восприятия прерываний специальные окна. Аппаратные прерывания вызываются электрическими сигналами на входах INTR и NMI.
В защищенном режиме, помимо прерываний существуют так называемые исключения (exceptions). Исключение происходит в результате нештатной ситуации выполнения программы, которую возможно необходимо обработать определенным образом. Исключения подразделяются на отказы, ловушки и аварийные завершения.
Отказ (fault) -- это исключение, которое обнаруживается и обслуживается до выполнения инструкции, вызывающей ошибку. После обслуживания этого исключения управление возвращается снова на ту же инструкцию (включая все префиксы), которая вызвала отказ. Отказы, использующиеся в системе виртуальной памяти, позволяют, например, подкачать с диска в оперативную память, затребованную страницу или сегмент.
Ловушка (trap) -- это исключение, которое обнаруживается и обслуживается после выполнения инструкции, его вызывающей. После обслуживания этого исключения управление возвращается на инструкцию, следующую за вызвавшей ловушку. К классу ловушек относятся и программные прерывания.
Аварийное завершение (abort) - это исключение, которое не позволяет точно установить инструкцию, его вызвавшую. Оно используется для сообщения о серьезной ошибке, такой как аппаратная ошибка или повреждение системных таблиц.
Обработка прерываний и исключений в защищенном режиме базируется на таблице дескрипторов прерываний (шлюзов прерываний) IDT адрес начала и размер которой хранятся в регистре IDTR. Его формат аналогичен формату регистра GDTR.
Таблица прерываний может содержать до 256 дескрипторов. При попытке обслуживания прерывания с номером, выходящим за размер таблицы, генерируется исключение #DF. Под исключения отданы первые 32 номера (0 31).
Не все из этих векторов используются процессором в настоящее время; не назначенные векторы из этого диапазона резервируются для возможного использования в будущем. Использовать не назначенные векторы не следует.
Векторы маскируемых прерываний определяются аппаратно. Контроллеры внешних прерываний (например, Intel 8259, программируемый контроллер прерываний) передают вектор на шину процессора во время цикла квитирования прерывания. Использоваться могут любые векторы в диапазоне значений от 32 до 255. В реальном режиме диапазон номеров для обработки аппаратных прерываний находился: IRQ0IRQ7 номера прерываний 08h0Fh и IRQ8IRQ15 - 70h77h. В связи с тем, что, как отмечалось выше, первые 32 номера заняты под исключения, возникает необходимость перепрограммировать контроллер прерываний на другие номера. Изначальным программирование контроллера для реального режима занимается BIOS. Итого в защищенном режиме остается 208 номеров под программные прерывания. Назначения векторов исключений и прерываний показаны в таблице.
Рестарт команды.
Для большей части исключений и прерываний передача управления не происходит до конца текущей команды. Тем самым регистр EIP устанавливается таким образом, чтобы указывать на команду, следующую за командой, которая выполнялась в момент генерации исключения или прерывания. Если эта команда имеет префикс повторения, то передача управления происходит в конце текущей итерации, причем все регистры будут находиться в состоянии для выполнения следующей итерации. Однако, если данная ситуация относится по типу к сбоям, то регистры процессора восстанавливаются в состояние, предшествующее выполнению вызвавшей сбой команды. Тем самым допускается рестарт команды.
Рестарт команды используется для обработки исключений, блокирующих доступ к операндам. Например, прикладная программа могла обратиться к данным в сегменте, не присутствующем в памяти. В случае такого исключения обработчик исключения должен загрузить отсутствующий нужный сегмент (возможно, с жесткого диска) и возобновить выполнение, начиная с команды, вызвавшей данное исключение. Во время исключения команда могла изменить содержимое некоторых регистров процессора. При считывании командой значения из стека необходимо восстановить прежнее значение указателя стека. Все эти восстановительные операции выполняются процессором способом, совершенно прозрачным для прикладной программы.
В случае сбоя регистр EIP восстанавливается таким образом, чтобы указывать на команду, вызвавшую исключение. При возврате из обработчика исключений выполнение программы продолжается с той же команды.
Приоритеты одновременно происходящих прерываний.
Анализ условий обслуживания прерываний и исключений выполняется в следующем порядке (по убыванию приоритета):
1. Проверка на исключение-ловушку отладки (#DS) по выполненной инструкции (пошаговый режим через флаг TF или точка останова по данным через регистры отладки).
2. Проверка на исключение-отказ отладки (#DB) по последующей инструкции (точка останова по инструкции через регистр отладки).
3. Немаскируемое прерывание (аппаратное по входу NMI).
4. Маскируемое прерывание (аппаратное по входу INTR при IF=1).
5. Проверка на исключение-отказ сегментации (#NP или #GP) при выборке следующей инструкции.
6. Проверка на исключение-отказ страницы (#PF) при выборке следующей инструкции.
7. Проверка на отказ декодирования следующей инструкции (#UD или #GP).
8. Для операции WAIT проверка TS и МР (исключение #NM, если TS=1 и МР=1).
9. Для операции ESCAPE (инструкция математического сопроцессора) проверка ЕМ и TS (исключение #NМ, если EМ=1 или TS=1).
10. Для операции WAIT или ESCAPE проверка на исключение #MF от сопроцессора.
11. Проверка на отказ сегментации (#NР, #SS, #GP) или отказ страницы (#PF) для операндов, используемых в инструкции.
Двойной отказ (Double Fault) -- исключение #DF -- возникает, когда при обработке исключения, связанного с сегментацией (#TS, #NP, #SS или #GP), процессор обнаруживает исключение, отличное от отказа страницы (#PF). Также двойной отказ возникает, если при обработке исключения отказа страницы #PF обнаруживается исключение другого типа. В этом случае тоже исполняется исключение #DF.
Если во время обслуживания исключения отказа страницы произойдет еще один отказ страницы, то происходит аварийный останов (Shutdown) процессора. Во время аварийного останова никакие новые инструкции не выполняются. Из этого состояния процессор можно вывести только аппаратно сигналом NMI, оставляя его в защищенном режиме, или сигналом RESET, переводящим процессор в реальный режим.
Прерывания и исключения процессора, работающего в защищенном режиме, приведены в таблице. В примечаниях отмечены случаи, когда исключение реального режима отличается от защищенного.
Механизмы передачи управления обработчикам прерываний.
Дескрипторная таблица прерываний (IDT) содержит шлюзы
Формат шлюза IDT
Поле «TYPE» в байте доступа определяет тип шлюза:
· 4 - шлюз вызова 80286 (Call Gate);
· 5 - шлюз задачи 80286 (Task Gate);
· 6 - шлюз прерывания 80286 (Interrupt Gate);
· 7 - шлюз ловушки 80286 (Trap Gate);
· C - шлюз вызова 386+ (Call Gate);
· D - шлюз задачи 386+ (Task Gate);
· Е - шлюз прерывания 386+ (Interrupt Gate);
· F - шлюз ловушки 386+ (Trap Gate).
Шлюз прерывания содержит адрес входа в обработчик прерывания в виде «селектор сегмента» и «смещение».
Шлюзы вызова (Call Gates) используются для вызовов процедур со сменой уровня привилегий, шлюзы задач (Task Gates) используются для переключения задач, шлюзы прерываний (Interrupt Gates) и ловушек (Trap Gates) определяют процедуры обслуживания прерываний. Шлюзы вызова позволяют автоматически копировать заданное число слов из старого стека в новый. Шлюзы прерываний отличаются от шлюзов ловушек только тем, что они запрещают прерывания (сбрасывают IF), а шлюзы ловушек -- нет.
Аналогично тому, как команда CALL вызывает процедуру или задачу, так и исключение или прерывание может "вызвать" обработчик прерывания, представленный в виде процедуры или задачи. Реагируя на исключение или прерывание, процессор использует вектор особого прерывания или прерывания в качестве индекса дескриптора в IDT. Если процессор индексирует шлюз прерывания или шлюз ловушки, то вызов обработчика происходит аналогично вызову при помощи CALL шлюза вызова. Если процессор индексирует шлюз задачи, это приводит к переключению задачи аналогично вызову при помощи CALL шлюза задачи.
Прерывания, использующие либо шлюзы прерывания, либо шлюзы ловушки, вызывают очистку флага TF после того, как его текущее значение сохранено в стеке как часть сохраняемого содержимого регистра EFLAGS. Поступая таким образом, процессор предотвращает воздействие трассировки команды на реакцию прерывания. Последующая команда IRET восстанавливает флаг TF в значение, сохраненное в регистре EFLAGS в стеке.
Различие между шлюзом прерывания и шлюзом ловушки состоит в их воздействии на флаг IF. Прерывание, использующее шлюз прерывания, очищает флаг IF, предотвращая тем самым влияние на текущий обработчик прерывания прочих возможных прерываний. Последующая команда IF восстанавливает флаг IF в состояние, которое он имел в сохраненном в стеке регистре EFLAGS. Прерывание, проходящее через шлюз ловушки, не изменяет флага IF.
Защита в процедурах прерываний.
Правило привилегированности, управляющее процедурами прерывания, аналогично правилу, действующему при вызове процедуры: процессор не разрешает прерыванию передавать управление процедуре в менее привилегированный сегмент (с численно большим номером уровня привилегированности). Попытка нарушить это правило ведет к генерации исключения защиты.
Поскольку прерывания, как правило, происходят не в заранее запланированное время, данное правило фактически накладывает ограничения на уровни привилегированности, с которыми могут выполняться процедуры обработки исключений и прерываний. Для защиты от нарушения правила привилегированности можно использовать один из следующих способов:
??Обработчик исключения или прерывания должен быть помещен в конформный кодовый сегмент. Этот способ может использоваться для обработчиков некоторых конкретных исключений (например, деления на ноль). Такие обработчики должны использовать только данные, доступные через стек. Если обработчику требуются данные из сегмента данных, этот сегмент данных должен иметь уровень привилегированности 3, то есть он должен быть незащищенным.
??Обработчик может быть помещен в кодовый сегмент с уровнем привилегированности 0. Такой обработчик будет выполняться всегда, независимо от CPL программы.
Код ошибки.
При отработке исключения в защищенном режиме процессор сохраняет в стеке слово кода ошибки (Error Code). Если оно отлично от нуля, то в нем содержится селектор дескриптора, с которым связана ошибка.
Код ошибки имеет формат, показанный на рисунке
Формат кода ошибки
Код ошибки похож на селектор сегмента, однако вместо поля RPL код ошибки содержит два однобитовых поля:
1. Процессор устанавливает бит EXT, если исключение вызвано событием, внешним по отношению к программе.
2. Процессор устанавливает бит IDT, если индексная часть кода ошибки ссылается к дескриптору шлюза в IDT.
Если бит IDT не установлен, то бит TI указывает на то, ссылается ли код ошибки к GDT (бит TI очищен), или же к LDT (бит TI установлен). Остальные 13 битов - это старшие биты селектора сегмента. В некоторых случаях код ошибки является пустым (т.е. все биты его младшего слова очищены.) Код ошибки помещается в стек в виде двойного слова. Это делается для выравнивания стека по адресам, кратным четырем. Старшая половина двойного слова резервируется.
Условия возникновения исключений.
Ниже подробнее опишем условия генерации тех или иных исключений. Каждое описание классифицирует исключение как сбой, ловушку или аварийное завершение. Такая классификация обеспечивает информацию, необходимую системным программистам для рестарта процедуры, в которой встретилось данное исключение.
Сбои - Сохраненное содержимое регистров CS и EIP указывает на команду, сгенерировавшую сбой.
Ловушки - Сохраненное содержимое регистров CS и EIP, записанное в момент срабатывания ловушки, указывает на команду, которая должна быть выполнена после команды, сгенерировавшей ловушку. Если ловушка обнаружена в команде передачи управления, сохраненное содержимое регистров CS и EIP отражает эту передачу управления. Например, если ловушка сработала в команде JMP, то сохраненное значение регистров CS и EIP указывает на адрес назначения перехода команды JMP, а не на команду в следующем адресе после команды JMP.
Аварийные завершения - это исключения, не позволяющие ни точного определения команды, вызвавшей его, ни рестарта программы, в которой произошло это исключение. Аварийные завершения используются для сообщения о серьезных ошибках, таких как аппаратные ошибки или противоречивые или недопустимые значения в системных таблицах.
Исключение 0 - Ошибка деления
Сбой типа "ошибки деления" встречается в командах DIV или IDIV, при делителе равном 0.
Исключение 1 - Отладочные исключения
Процессор генерирует исключения для нескольких условий: то, является ли данное исключение сбоем или ловушкой, зависит от условия, как показано ниже:
??Сбой в контрольной точке адреса команды;
??Ловушка в контрольной точке адреса данных;
??Ловушка шага выполнения;
??Ловушка контрольной точки переключения задачи.
Процессор не помещает код ошибки для данного исключения в стек. Обработчик прерывания может исследовать отладочные регистры для того, чтобы определить, какое условие вызвало исключение.
Исключение 3 - Контрольная точка
Команда INT 3 генерирует ловушку типа контрольной точки. Команда INT 3 имеет длину один байт, что упрощает замену кода операции в кодовом сегменте в оперативной памяти кодом операции контрольной точки. Операционная система или система отладки может использовать сегмент данных, отображенный в том же физическом адресном пространстве, что и кодовый сегмент, для помещения команды INT 3 в точках, где желательно вызвать отладчик. Отладчики используют контрольные точки для приостановки выполнения программы, чтобы иметь возможность исследовать регистры, переменные программы и т.д.
Сохраненное содержимое регистров CS и EIP указывает на байт, следующий за контрольной точкой. Если отладчик позволяет возобновление приостановленной программы, он заменяет команду INT 3 исходным кодом операции по адресу контрольной точки, а также декрементирует сохраненное содержимое регистра EIP перед возвратом.
Исключение 4 - Переполнение
Ловушка переполнения происходит, когда процессор выполняет команду INTO при установленном флаге IF. Поскольку арифметические операции со знаком и без знака используют некоторые общие команды, процессор не в состоянии определить, когда фактически происходит переполнение. Вместо этого он устанавливает флаг OF, когда результаты, интерпретируемые как числа со знаком, выходят за пределы допустимого диапазона. При выполнении арифметических операций с операндами, имеющими знак, флаг OF можно тестировать непосредственно, либо при помощи команды INTO.
Исключение 5 - Контроль диапазона
Сбой типа "контроля диапазона" генерируется процессором, когда при выполнении команды BOUND обнаруживается, что операнд превышает заданные границы. Программа может использовать команду BOUND для контроля того, что индекс массива, имеющий знак, находится в пределах, определенных для этого блока памяти.
Исключение 6 - Неверный код операции
Сбой "неверного кода операции" генерируется, когда исполнительный модуль обнаруживает неверный код операции. (Данное исключение не будет обнаружено до тех пор, пока не будет сделана попытка выполнить неверный код операции; т.е. предварительная выборка неверного кода операции, без выполнения, не ведет к данному исключению). Код ошибки в данном случае на стек не помещается. Такое исключение может обрабатываться в пределах той же задачи.
Это исключение происходит также при неверном типе операнда для данного кода операции. Примером может служить команда межсегментного перехода JMP, использующая регистровый операнд, либо команда LES с регистровым исходным операндом.
Третье условие генерации данного исключения состоит в использовании префикса LOCK с командой, для которой захват шины невозможен. Только определенные команды могут работать с захватом шины, и из них могут использоваться только те, что выполняют запись по адресу назначения в памяти. Все прочие использования префикса LOCK приводят к генерации исключения неверного кода операции.
Неопределенные коды операций:
-----------------------------------------------------------------
Однобайтовые
-----------------------------------------------------------------
82
D6
F1
-----------------------------------------------------------------
Двухбайтовые
-----------------------------------------------------------------
0F 07
0F 10
0F 11
0F 12
0F 13
F6 XX
F7 XX
C0 XX
C1 XX
D0 XX
D1 XX
D2 XX
D3 XX
-----------------------------------------------------------------
Выше приведенные инструкции зарезервированы «на будущее». Эти коды операций прерывания 6 не генерируют.
Исключение 7 - Устройство недоступно
Сбой типа "устройство недоступно" генерируется при одном из двух следующих условий:
??Процессор выполняет команду ESC при установленном бите EM регистра CR0;
??Процессор выполняет команду WAIT или ESC при установленном бите TS регистра CR0.
Таким образом, прерывание 7 происходит, когда программист хочет, чтобы команда ESC обрабатывалась программно (бит EM установлен), либо когда встречена команда WAIT или ESC, а контекст модуля операций с плавающей точкой отличен от контекста для текущей задачи.
Для процессоров 80286 и 386 бит MP регистра CR0 используется с битом TS для определения того, должна ли команда WAIT генерировать исключение. Для программ, выполняемых на процессоре i486, бит MP должен быть установлен всегда.
Исключение 8 - Двойной сбой
Обычно когда процессор обнаруживает исключение при попытке вызвать обработчик исключения, происшедшей ранее, эти два исключения могут обрабатываться последовательно. Однако, если процессор не в состоянии этого сделать, он генерирует исключение двойного сбоя. Для того, чтобы определить, когда о двух сбоях следует сообщить как о двойном сбое, процессор делит исключения на три класса: незначительные исключения (1-7,16), значительные исключения (0,10-13) и страничные сбои (14).
Когда происходит два незначительных исключения или прерывания, либо одно незначительное и одно значительное, то два таких события могут обрабатываться последовательно. В случае двух значительных событий они не могут быть обработаны, и тогда генерируется исключение двойного сбоя.
Если за незначительным или значительным исключением следует страничный сбой, то два таких события могут быть обработаны последовательно. Это также справедливо и в том случае, когда сначала следует страничный сбой, а за ним незначительное исключение. Однако, если за страничным сбоем следует значительное исключение или еще один страничный сбой, то генерируется аварийное завершение типа "двойной сбой".
Любые последующие сбои, генерируемые при попытках процессора передать управление соответствующему обработчику прерывания, могут также привести к ситуации двойного сбоя.
Процессор всегда помещает код ошибки в стек обработчика двойного сбоя, однако этот код ошибки всегда равен 0. Рестарт вызвавшей сбой команды невозможен. Если при попытке вызвать обработчик двойного сбоя произойдет еще одно исключение, процессор входит в режим закрытия системы. Этот режим аналогичен состоянию, следующему за выполнением команды HLT. Никакие дальнейшие команды не выполняются до приема немаскируемого прерывания или сигнала сброса системы RESET. Если закрытие системы происходит во время выполнения процессором обработчика немаскируемого прерывания, то рестарт процессора возможен только при помощи сигнала RESET. Процессор генерирует специальный цикл шины, указывающий на вхождение процессора в режим закрытия.
Исключение 9 - (Резервируется Intel. Не использовать!)
Прерывание 9, аварийное завершение выхода за границы сегмента сопроцессора, генерируется в системе центрального процессора 386/математического сопроцессора 387, когда процессор 386 обнаруживает нарушение границы страницы или сегмента при пересылке средней части операнда математического сопроцессора 387. Это прерывание процессором i486+ не генерируется; вместо него происходит прерывание 13.
Исключение 10 - Неверный TSS
Сбой типа "неверный TSS" генерируется при попытке переключения задачи на сегмент с неверным TSS. TSS является неверным в случаях, описанных в таблице ниже. Код ошибки помещается в стек обработчика исключений, что помогает идентифицировать причину сбоя. Бит EXT указывает, что исключение было вызвано условием вне управления программы (например, внешнее прерывание, используя шлюз задачи, попыталось выполнить переключение задачи на неверный TSS).
--------------------------------------------------------------------------------------------
Индекс кода ошибки Описание
--------------------------------------------------------------------------------------------
Сегмент TSS Граница сегмента TSS меньше 67H
Сегмент LDT Неверная LDT или LDT не присутствует
Сегмент стека Селектор сегмента стека превышает границу таблицы дескрипторов
Сегмент стека Сегмент стека не доступен для записи
Сегмент стека DPL сегмента стека не совместим с CPL
Сегмент стека RPL селектора сегмента стека не совместим с CPL
Сегмент кода Селектор сегмента кода превышает границу таблицы дескрипторов
Сегмент кода Сегмент кода не является выполняемым
Сегмент кода DPL не конформного сегмента кода не равен CPL
Сегмент кода DPL конформного сегмента кода больше CPL
Сегмент данных Селектор сегмента данных превышает границу таблицы дескрипторов
Сегмент данных Сегмент данных не доступен для чтения
--------------------------------------------------------------------------------------------
Данный сбой может происходить как в контексте исходной задачи, так и в контексте новой задачи. До тех пор, пока процессор полностью не убедится в присутствии нового TSS, исключение происходит в контексте исходной задачи. Как только присутствие нового TSS будет подтверждено, переключение задачи считается завершенным, т.е. регистр TR загружен селектором нового TSS, и если переключение задачи является следствием CALL или прерывания, то поле Компоновки нового TSS будет содержать ссылку на старый TSS. Любые ошибки, обнаруженные процессором после этой точки, обрабатываются в контексте новой задачи.
Чтобы гарантировать доступность TSS для обработки исключения, обработчик исключения типа "неверный TSS" должен вызываться как задача посредством шлюза задачи.
Исключение 11 - Сегмент не присутствует
Сбой типа "сегмент не присутствует" генерируется, когда процессор обнаруживает, что бит Присутствия в дескрипторе очищен. Процессор может генерировать данный сбой в одном из следующих случаев:
??При попытке загрузить регистры CS, DS, ES, FS или GS; однако, загрузка регистра SS вызывает сбой стека.
??При попытке загрузить регистр LDT при помощи команды LLDT, однако, загрузка регистра LDT во время операции переключения задачи вызывает исключение "неверный TSS".
??При попытке использовать дескриптор шлюза, помеченный признаком "сегмент не присутствует".
Данный сбой позволяет выполнение рестарта. Если обработчик исключений загружает сегмент и возвращается, то прерванная программа продолжает выполнение.
Если исключение "сегмент не присутствует" происходит во время переключения задачи, то не все шаги переключения задачи завершаются. При переключении задачи процессор сначала загружает все сегментные регистры, а затем проверяет допустимость их содержимого. При обнаружении исключения "сегмент не присутствует" остальные сегментные регистры не проверяются, и следовательно, не могут быть использованы для ссылок к памяти. Обработчик исключения "сегмент не присутствует" не должен полагаться на возможность использования селекторов сегментов, находящихся в регистрах CS, SS. DS, ES, FS и GS без возникновения еще одного исключения. Обработчик должен проверять все сегментные регистры перед тем, как пытаться возобновить выполнение новой задачи; в противном случае, далее могут произойти сбои общей защиты, причем в условиях, которые сделают диагностирование еще более затруднительным. Для обработки этого случая имеется три способа:
1. Обработка сбоя "сегмент не присутствует" в задаче. Обратное переключение на прерванную задачу заставит процессор проверить все регистры при загрузке их из TSS.
2. Использование для всех сегментных регистров команд PUSH и POP. Каждая команда POP заставит процессор проверить новое содержимое сегментного регистра.
3. Проверка сохраненного в TSS значения каждого сегментного регистра при помощи симуляции теста, выполняемого процессором при загрузке сегментного регистра.
Данное исключение помещает в стек код ошибки. Бит EXT кода ошибки устанавливается в том случае, если внешнее по отношению к программе событие вызвало прерывание, которое затем привело к ссылке на не присутствующий сегмент. Бит IDT устанавливается, если код ошибки выполняет ссылку на элемент IDT (например, команда INT, ссылающаяся на не присутствующий шлюз).
Операционная система обычно использует исключение "сегмент не присутствует" для реализации на сегментном уровне виртуальной памяти. Однако, обозначение не присутствия сегмента в дескрипторе шлюза обычно не означает, что сегмент не присутствует (поскольку шлюзы не обязательно должны соответствовать сегментам). Не присутствующие шлюзы могут использоваться операционной системой для переключения исключений, имеющих специальное значение для операционной системы.
Исключение 12 - Исключение в стеке
Сбой в стеке генерируется в двух следующих случаях:
??В результате нарушения границы операцией, ссылающейся к регистру SS. Сюда входят стеко-ориентированные команды, такие как POP, PUSH, ENTER и LEAVE, а также прочие ссылки к памяти, неявно использующие стек (например, MOV AX,[BP+6]). Команда ENTER генерирует данное исключение, когда не хватает памяти для распределения локальных переменных.
??При попытке загрузить регистр SS дескриптором, отмеченным признаком "сегмент не присутствует", и допустимым во всех прочих отношениях. Это может произойти при переключении задачи, при выполнении команды CALL к другому уровню привилегированности, при возврате к другому уровню привилегированности, команде LSS, либо MOV или POP для регистра SS.
Когда процессор обнаруживает исключение в стеке, он помещает код ошибки в стек обработчика исключений. Если исключение произошло в следствии не присутствующего сегмента стека или переполнения нового стека во время выполнения межуровневой команды CALL, то код ошибки содержит селектор сегмента, вызвавшего исключение (обработчик исключений может проверять бит Присутствия в дескрипторе для того, чтобы определить, какое исключение имело место); в противном случае код ошибки равен 0.
Команда, генерирующая данный сбой, позволяет рестарт во всех случаях. Адрес возврата, помещенный в стек обработчика исключений, указывает на команду, рестарт которой требуется выполнить. Эта команда обычно та, что вызвала исключение; однако, в случае исключительной ситуации в стеке вследствие загрузки дескриптора не присутствующего сегмента стека во время переключения задачи указанная команда представляет собой первую команду новой задачи.
Когда исключение в стеке происходит при переключении задачи, сегментные регистры не могут служить для адресации памяти. Во время переключения задачи значения селекторов загружаются до проверки дескрипторов. При генерации исключения стека остальные сегментные регистры остаются непроверенными, что может привести при их использовании к исключениям. Обработчик сбоев стека должен проверить все сегментные регистры, прежде чем пытаться возобновить выполнение новой задачи; в противном случае могут быть сгенерированы исключения общей защиты в условиях, когда диагностирование более затруднительно.
Исключение 13 - Общая защита
Исключение общей защиты генерируется для всех нарушений памяти, не вызывающих прочих исключений. Сюда входят (но не ограничивают перечень):
????Превышение границы сегмента при использовании сегментов CS, DS, ES, FS или GS.
????Превышение границы сегмента при ссылке к таблице дескрипторов.
????Передача выполнения сегменту, не являющемуся выполняемым (кодовым) сегментом.
????Попытка записи в сегмент данных, доступный только для чтения, или в кодовый сегмент.
????Чтение из кодового сегмента, доступного только для выполнения.
????Загрузка регистра SS селектором сегмента, доступного только для чтения (если только этот селектор не берется из TSS при переключении задачи, так как в этом случае происходит исключение "неверный TSS").
????Загрузка регистра SS, DS, ES, FS или GS селектором системного сегмента.
????Загрузка регистра DS, ES, FS или GS селектором кодового сегмента, доступного только для выполнения.
????Загрузка регистра SS селектором выполняемого сегмента.
????Доступ к памяти при помощи регистров DS, ES, FS или GS, когда в них содержится пустой селектор.
????Переключение на Занятую задачу.
????Нарушение правил привилегированности.
????Превышение длины команды предельного значения 15 байтов (это может случиться только при использовании перед командой избыточных префиксов).
????Загрузка регистра CR0 при установленном бите PG (подкачка страниц разрешена) и очищенном бите PE (защита запрещена).
????Прерывание или исключение через шлюз прерывания или ловушки из виртуального режима 8086 к обработчику с уровнем привилегированности иному, нежели 0.
Исключение общей защиты по типу относится к сбою. В ответ на исключение общей защиты процессор помещает в стек обработчика исключений код ошибки. Если исключение вызвано загрузкой дескриптора, то код ошибки содержит селектор для данного дескриптора; в противном случае код ошибки является пустым. Источник для селектора в коде ошибки может представлять собой одно из:
1. Операнд команды.
2. Селектор из шлюза, являющегося операндом команды.
3. Селектор из TSS, участвующего в переключении задачи.
Исключение 14 - Страничный сбой
Страничный сбой происходит, когда подкачка страниц разрешена (бит PG регистра CR0 установлен) и процессор обнаруживает одно из следующих условий во время трансляции линейного адреса в физический:
??Элемент каталога страниц или таблицы страниц, необходимый для трансляции адреса, имеет очищенный бит Присутствия, что означает, что таблица страниц или страница, содержащая операнд, не присутствует в физической памяти;
??Процедура не имеет достаточного уровня привилегированности для доступа к указанной странице.
Процессор обеспечивает для обработчика страничного сбоя два информационных элемента, помогающих диагностировать исключение и восстановить нормальные условия:
??Код ошибки в стеке. Код ошибки для страничного сбоя имеет формат, отличный от формата для других особых ситуаций (см. выше). Код ошибки сообщает обработчику исключения следующие три вещи:
1. Произошло ли данное исключение вследствие того, что страница не присутствует, или из-за нарушения прав доступа к странице.
2. Работал ли процессор в момент исключения в режиме пользователя, или в режиме супервизора.
3. Состоял ли доступ к памяти, вызвавший данное исключения, в чтении или в записи.
??Содержимое регистра CR2. Процессор загружает в регистр CR2 32 - разрядный линейный адрес, сгенерировавший исключение. Обработчик исключения может использовать данный адрес для нахождения соответствующих элементов каталога страниц и таблицы страниц. Если во время выполнения обработчика страничного сбоя произойдет еще один страничный сбой, то обработчик должен поместить содержимое регистра CR2 в стек.
Страничный сбой при переключении задачи
Следующие операции выполняют доступ к памяти при переключении задачи:
1. Запись состояния исходной задачи в TSS для этой задачи.
2. Чтение GDT для нахождения дескриптора TSS новой задачи.
3. Чтение TSS новой задачи для проверки типов дескрипторов сегмента из TSS.
4. Может быть выполнено чтение LDT новой задачи для верификации сегментных регистров, хранимых в новом TSS.
Страничный сбой может являться результатом обращения к одной из этих операций. В двух последних случаях исключение происходит в контексте новой задачи. Указатель команд указывает на следующую команду новой задачи, а не на команду вызвавшую переключение задачи (или на последнюю выполняемую команду в случае прерывания). Если устройство операционной системы позволяет страничным сбоям происходить вовремя переключения задач, то обработчик страничного сбоя должен вызываться через шлюз задачи.
Страничный сбой при противоречивом значении указателя стека
Следует обращать особое внимание на то, чтобы страничный сбой не приводил к использованию процессором неверного указателя стека (SS:ESP). Программное обеспечение, написанное для 16-битовых процессоров Intel, часто использует для переключения на новый стек пару команд, например,
MOV SS, AX
MOV SP, StackTop
В случае процессора i486+, поскольку вторая команда обращается к памяти, можно получить в данном случае страничный сбой после того, как был изменен селектор сегментного регистра SS, но перед тем, как соответственно было изменено содержимое регистра SP. В этой точке две части указателя стека SS:SP (разумеется, для 32-разрядных программ это SS:ESP) противоречивы друг с другом. Новый стековый сегмент используется со старым указателем стека.
Процессор не использует противоречащий указатель стека, если обработка страничного сбоя вызывает переключение стека на хорошо определенный стек (т.е. обработчик это задача или более привилегированная процедура). Однако, если страничный сбой происходит на том же уровне привилегированности и в той же задаче, что и для обработчика страничного сбоя, то процессор попытается использовать стек, на который указывает противоречивый указатель стека.
В системах, использующих подкачку страниц и обрабатывающих страничные сбои в пределах задач, содержащих сбой (посредством шлюзов ловушки или прерывания), программное обеспечение, выполняемое на том же уровне привилегированности, что и обработчик страничного сбоя, должно инициализировать новый стек командой LSS, а не парой команд, показанной выше. Если обработчик страничного сбоя работает на уровне привилегированности 0 (нормальный случай), проблема ограничивается программами, работающими на уровне привилегированности 0, т.е. обычно ядром операционной системы.
Исключение 16 - Ошибка операции с плавающей точкой
Сбой операции с плавающей точкой говорит об ошибке, генерируемой командой арифметической операции с плавающей точкой. Прерывание 16 может произойти, только если бит NE регистра CR0 установлен.
Исключение 17 - Проверка выравнивания
Сбой проверки выравнивания может генерироваться при доступе к невыравненным операндам. Например, слово, записанное по нечетному адресу памяти, или двойное слово, записанное по адресу, не кратному четырем. В таблице ниже приводятся требования к выравниванию по типам данных. Для разрешения контроля выравнивания должны выполняться следующие условия:
??Бит AM регистра CR0 должен быть установлен;
??Флаг AC должен быть установлен;
??CPL должен быть равен 3 (уровень пользователя).
-----------------------------------------------------------------
Тип данных Адрес должен нацело делиться на
-----------------------------------------------------------------
Слово 2
Двойное слово 4
Короткое вещественное 4
Длинное вещественное 8
Временное вещественное 8
Селектор 2
48-разрядный сегментированный указатель 4
32-разрядный плоский указатель 4
32-разрядный сегментированный указатель 2
48-разрядный "Псевдо-дескриптор" 4
Область хранения FSTENV/FLDENV 4 или 2, в зависимости _____________________________________________ от размера операнда
Область хранения FSAVE/FRSTOR 4 или 2, в зависимости _____________________________________________ от размера операнда
Битовая строка 4
-----------------------------------------------------------------
Проверку выравнивания полезно использовать в программах, в которых два младших бита указателей служат для идентификации адресуемой ими структуры данных. Например, подпрограмма в библиотеке математических функций может принимать указатели на числовые структуры данных. Если типу этой структуры в двух младших битах указателей на этот тип назначен код 10 (двоичный), математические подпрограммы могут выполнить для этого кода типа коррекцию, добавляя смещение -10 (двоичное). Если подпрограмма получит неверный тип указателя, то произойдет невыравненная ссылка, что приведет к генерации исключения.
Сбои проверки выравнивания генерируются только в режиме пользователя (уровень привилегированности 3). Ссылки к памяти с уровнем привилегированности по умолчанию 0, такие как загрузка дескриптора сегмента, не генерируют сбоев проверки выравнивания, даже если они вызваны ссылками к памяти, выполненными в пользовательском режиме.
Запись 48-разрядного псевдо-дескриптора (образа памяти для содержимого базового регистра таблицы дескрипторов) в режиме пользователя может генерировать сбой проверки выравнивания. Хотя программы режима пользователя обычно не сохраняют псевдодескрипторов, такого сбоя можно избежать, выравнивая псевдодескриптор по адресу нечетного слова (т.е. адресу, являющемуся 2 MOD 4).
Команды FSAVE и FRSTOR генерируют невыравненные ссылки, которые могут вызвать сбой проверки выравнивания. Прикладным программам эти команды нужны редко.
Часть 2. Распределение оперативной памяти в Windows 95-98
Для загрузки операционные системы Windows 95/98 используют операционную систему MS DOS 7.0 (MS DOS 98), и в случае если в секции [Options] файла MSDOS.SYS имеется строка BootGUI = 0, процессор работает в обычном реальном режиме (см.главу 4). Распределение памяти в MS DOS 7.0 такое же, как и в предыдущих версиях DOS. Однако при загрузке интерфейса GUI перед загрузкой ядра Windows 95/98процессор переключается в защищенный режим работы и начинает распределять память уже с помощью страничного механизма.
Приложения и подсистемы Windows 9x (за исключением ядра) никогда не работают с физической памятью. Разделение на виртуальную и физическую память является ключевым аспектом работы системы. Приложения и подсистемы Windows 9х имеют дело с определенными интерфейсами прикладного программирования и виртуальными адресными пространствами. Базовая система работает как с физической памятью, так и с виртуальными адресными пространствами.
В основе поддержки виртуальных машин и виртуального адресного пространства, которую обеспечивают операционные системы Windows 9x, лежит работа с реальной (физической) памятью компьютера, ограниченной в своих размерах. Операционная система выгружает неактивные страницы памяти виртуальных адресных пространств выполняющихся процессов из оперативной памяти на диск и загружает страницу, запрошенную при выполнении текущей команды. Другими словами, загрузка страницы в оперативную память осуществляется по требованию, как это принято в большинстве операционных систем, использующих страничный механизм организации виртуальной памяти. В то же время, освобождается оперативная память от неактивных страниц группами по нескольку страниц за одну операцию. Реализованный в операционных системах Windows 9x алгоритм замещения представляет собой стандартную дисциплину LRU (Least Recently Used -- дольше других неиспользуемый), заключающуюся, как мы уже знаем, в освобождении тех страниц физической памяти, которые дольше других не использовались.
Многие страницы физической памяти компьютера не участвуют в замещении, они распределены постоянно. Их занимают, в частности, резидентные компоненты ядра. На эти цели отводится примерно один мегабайт памяти. За оставшуюся физическую память конкурируют различные программы: динамически загружаемые компоненты системы и загружаемые виртуальные драйверы устройств, код и данные приложений, а также динамически размещаемые данные, такие как области кэширования, необходимые для работы файловой системы, и буферы прямого доступа к памяти (DMA).
В отличие от тех мультитерминальных систем, в которых операционная система должна заботиться о равноправном совместном использовании ресурсов, в системах Windows 9x сделано иначе. Поскольку это однопользовательские операционные системы, они позволяют заполнять память так, как это нужно пользователю и его программам. Динамически загружаемые компоненты системы конкурируют за память с прикладными программами. Если пользователь хочет, чтобы его приложение работало быстрее, ему будет позволено занять столько памяти, сколько вообще возможно.
Система накладывает ограничение на максимальный объем памяти, который может быть отдан в распоряжение отдельных приложений, -- если не следить за этим, становится возможным возникновение тупиковых ситуаций. После того как вся физическая память заполнена, первый же новый запрос на выделение памяти инициирует замещение страниц. Интересным побочным эффектом такого подхода является то, что у приложений нет надежного способа определения объема памяти, доступного в системе. Функция API GlobalMemorySatusQ возвращает целый ряд параметров, характеризующих состояние системной памяти, однако это не более чем «мгновенный снимок» текущей обстановки -- еще один вызов этой функции вполне может дать другие значения.
Страницы поступают в память и уходят из нее по-разному: в большинстве случаев они либо непосредственно размещаются в выделенной для этого памяти (как результат соответствующих запросов), либо загружаются при старте программы из ЕХЕ-файла приложения. Впоследствии эти страницы начинают перемещаться между физической памятью и файлом подкачки. Страницы, в которых содержится только код 32-разрядных приложений и динамически связываемых библиотек (DLL), система всегда загружает только из исходных исполняемых файлов.
Для того чтобы облегчить управление всем разнообразием типов страниц памяти, каждая активная страница, то есть каждая страница, которая является частью выполняющегося в данный момент системного модуля или приложения, снабжена хранящимся совместно с ней страничным дескриптором (Page Descriptor, PD). В этом дескрипторе содержатся адреса процедур, которые занимаются перемещением страницы из памяти на диск и обратно. Независимо от того, что именно находится в данной странице, диспетчер физической памяти, чтобы переместить страницу в оперативную память или из нее, просто вызывает соответствующую функцию, адрес которой определен в поле дескриптора страницы. В случае, если некоторая страница еще никогда не заполнялась, она называется абсолютно чистой (virgin). Например, именно так обозначаются страницы, содержащие код, использующий вызовы Win32. После того как с момента размещения страницы в памяти в нее будет в первый раз произведена запись данных, она считается испорченной (tainted) и может быть либо грязной (dirty), либо чистой (clean), в зависимости от того, осуществлялась ли в нее запись с момента последней ее подкачки в физическую память. Если запись в эту страницу производилась, и в этой физической странице требуется разместить иную виртуальную страницу, ее содержимое должно быть сохранено в файле подкачки.
Для наблюдения за распределением памяти и использованием иных ресурсов компьютера можно воспользоваться, например, программой SYSMON.EXE (системный монитор). Эта программа входит в состав утилит операционных систем Windows9х, поэтому после ее установки команда для ее запуска располагается в подменю Служебные меню Стандартные. Она позволяет выбрать интересующие нас параметры и наблюдать за их текущими значениями.
Использование так называемой плоской модели памяти, когда программист может использовать только один сегмент кода и один сегмент данных, которые имеют максимально возможные размеры, определяемые системными соглашениями операционной системы, приводит к тому, что с точки зрения программиста память получается неструктурированной. Программы используют классическую малую (small) модель памяти [40]. Каждая прикладная программа определяется 32-разрядными адресами, в которых сегмент кода имеет то же значение, что и сегменты данных. Единственный сегмент программы отображается непосредственно в область виртуального линейного адресного пространства, которая, в свою очередь, состоит из 4-килобайтных страниц. Каждая страница может располагаться где угодно в оперативной памяти (естественно, в том месте, где ее разместит диспетчер памяти, который сам находится в невыгружаемой области) или быть «сброшена»на диск, если не запрещено использовать страничный файл.
В операционных системах Windows 9x младшие адреса виртуального адресного пространства совместно используются всеми процессами. Это сделано для совместимости с драйверами устройств реального режима, резидентными программами и некоторыми 16-разрядными программами Windows. Безусловно, это плохое решение с точки зрения надежности, поскольку оно приводит к тому, что любой процесс может непреднамеренно (или же, наоборот, специально) испортить компоненты, находящиеся в этих адресах.
В Windows 9x каждая 32-разрядная прикладная программа выполняется в собственном адресном пространстве, но все они используют совместно один и тот же32-разрядный системный код. Доступ к чужим адресным пространствам в принципе возможен. Другими словами, виртуальные адресные пространства не задействуют всех аппаратных средств защиты, заложенных в микропроцессор. В результате неправильно написанная 32-разрядная прикладная программа может привести к аварийному сбою всей системы. Все 16-разрядные прикладные программы Windows разделяют общее адресное пространство, поэтому они так же уязвимы друг для друга, как и в среде Windows 3.X.
Собственно системный код Windows 9x размещается выше границы 2 Гбайт. В пространстве с отметками 2 и 3 Гбайт находятся системные библиотеки DLL, используемые несколькими программами. Напомним, что в 32-разрядных микропроцессорах семейства i80x86 имеется четыре уровня защиты, именуемые кольцами с номерами от 0 до 3. Кольцо с номером 0 является наиболее привилегированным, то есть максимально защищенным. Компоненты операционных систем Windows 9x, относящиеся к кольцу 0, отображаются на виртуальное адресное пространство между 3 и 4 Гбайт. К этим компонентам относятся собственно ядро Windows, подсистема управления виртуальными машинами, модули файловой системы и драйверы виртуальных устройств (VxD).
Область памяти между 2 и 4 Гбайт адресного пространства каждой 32-разряднойприкладной программы совместно используется всеми 32-разрядными прикладными программами. Такая организация позволяет обслуживать вызовы API непосредственно в адресном пространстве прикладной программы и ограничивает размер рабочего множества. Однако за это приходится расплачиваться снижением надежности. Ничто не может помешать программе, содержащей ошибку, произвести запись в адреса, принадлежащие системным библиотекам DLL, и вызвать крах всей системы.
В области между 2 и 3 Гбайт также находятся все запускаемые 16-разрядные прикладные программы Windows. С целью обеспечения совместимости эти программы выполняются в совместно используемом адресном пространстве, где они могут испортить друг друга так же, как и в Windows 3.x.
Адреса памяти ниже 4 Мбайт также отображаются в адресное пространство каждой прикладной программы и совместно используются всеми процессами. Благодаря этому становится возможной совместимость с существующими драйверами реального режима, которым необходим доступ к этим адресам. Это делает еще одну область памяти не защищенной от случайной записи. К самым нижним адресам (менее 64 Кбайт) этого адресного пространства 32-разрядные прикладные программы обращаться не могут, что дает возможность перехватывать неверные указатели, но 16-разрядные программы, которые, возможно, содержат ошибки, могут записывать туда данные.
В операционных системах Windows термином модуль (module) называют присутствующую в памяти совокупность кода, данных и других ресурсов (в частности таких, как битовые массивы). Обычно такая совокупность объектов представляет собой отдельную прикладную программу или библиотеку DLL. Windows формирует и поддерживает структуру данных под названием база данных модулей (module database), в которой учитываются все активные в данный момент модули системы. База данных модулей описывает статическую совокупность объектов в отличие от той динамической, что поддерживает база данных задач. Учет загруженных в данный момент модулей необходим, потому что он служит основой поддерживаемого Windows 9x механизма совместного использования ресурсов. Так, например, когда мы вторично запускаем программу Word или Internet Explorer, операционная система Windows обнаруживает, что сегменты кода и формирующий значок этой программы -- битовый массив уже загружены, и вместо того чтобы загружать еще одну копию, которая только отнимет память, она попросту заводит дополнительные ссылки на уже используемые ресурсы.
На протяжении всего времени работы системы Windows 9x для каждого ресурса поддерживают счетчик обращений к нему. По мере того как приложения используют тот или иной ресурс, Windows 9x увеличивают значение соответствующего счетчика, а по завершении работы приложения уменьшают его. Значение счетчика, равное нулю, свидетельствует о том, что ресурс больше не используется, а значит, система может удалить ресурс и освободить память, которую он занимал.
Подобные документы
Проектирование механизма обработки прерываний. Контроллер прерываний Intel 82C59A. Ввод-вывод по прерыванию. Программируемый контроллер интерфейса Intel 82C55A. Роль процессора в обработке прерывания ввода-вывода. Обзор алгоритма обработки прерывания.
контрольная работа [8,0 M], добавлен 19.05.2010Принципы и алгоритмы обработки прерываний. Набор действий по реализации этапов обработки прерываний микропроцессора. Разработка структуры и алгоритма резидентной программы. Реализация программы на языке Ассемблер, методы её отладки и тестирования.
курсовая работа [348,7 K], добавлен 22.12.2014Принципы организации и особенности обработки прерываний на основе контроллера 8259A. Общая характеристика аппаратных средств системы прерываний PIC (Programmable Interrupt Controller). История разработки и порядок работы с технологией Plag and Play.
курсовая работа [305,1 K], добавлен 29.07.2010Прерывание и его природа. Контролер прерываний. Обработка прерываний в реальном режиме. Характеристики реального режима работы микропроцессора. Схема обработки прерываний в реальном режиме. Написание собственного прерывания. Разработка в общем случае.
доклад [347,0 K], добавлен 22.09.2008Изучение понятия, векторов и механизмов обработки прерываний; их классификация в зависимости от источника происхождения. Особенности реагирования аппаратной и программной частей операционной системы на сигналы о совершении некоторого события в компьютере.
реферат [995,8 K], добавлен 22.06.2011Особенности и принцип действия файловой системы NTFS - одной из самых сложных и удачных из существующих на данный момент файловых систем. Функции файловой системы NTFS: разреженные файлы, журнал изменений, компрессия файлов и каталогов, жесткие связи.
реферат [17,4 K], добавлен 24.12.2010Структура раздела, MFT и его структура, метафайлы и их назначение. Каталоги, возможности безопасности, требуемые для файловых серверов и высококачественных персональных компьютеров в корпоративной среде. Главная файловая таблица, атрибуты файла NTFS.
реферат [35,0 K], добавлен 30.04.2010Основные возможности файловой системы NTFS. Введение механизма транзакции. Модель распределения дискового пространства. Объектная модель безопасности NT. Количество файлов в корневом и некорневом каталогах. Структура и атрибуты файла в системе NTFS.
реферат [19,8 K], добавлен 23.10.2011Файловая система как "пространство", в котором размещаются файлы. Типы файлов, их логическая организация. Файловая система FAT32: структура и кластеры. Структура файловой системы NTFS, ее каталоги. Сравнительная характеристика систем FAT32 и NTFS.
статья [436,0 K], добавлен 14.05.2010Хранение файлов, доступ к ним, установка и изменение атрибутов. Операционные системы DOS, Windows 95/98/Me, Windows NT/2000/XP. Файловая система FAT 16. Уменьшение потерь дискового пространства. Количество секторов в кластере. Главная загрузочная запись.
реферат [72,9 K], добавлен 19.01.2012