Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СППО-Вопросы к экзамену-2014 (Восстановлен).doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
1.16 Mб
Скачать
  1. Средства защиты памяти: изоляция адресных пространств. Поддержка в Intel.

Средства защиты памяти.

Можно выделить следующие подходы к защите памяти: 1) Изоляция адресных пространств процесс может видеть только свою память. 2) Кольцевая защита (по уровням привилегий). Расшифровка 1) метод замков и ключей. Каждая область памяти, которая выделяется отдельному процессу, получает уникальный код (“замок”) + информацию о разрешенных операциях. При обращении к памяти каждая программа указывает адрес (“предъявляет ключ”) для обращения к памяти. Изоляция адресных пространств на уровне сегментов может быть выполнена с помощью LDT, описывает сегменты, принадлежащие задаче. Расшифровка 2) Intel поддерживает 4 уровня привилегий: (3) User(прикладные программисты) (2) СУБД (разработчики комплексных систем) (1) Утилиты (более подвижные изменен, менее критичные) (0) Ядро ОС (наиболее критичные, менее изменяемые). MS-dos использовала только один уровень – нулевой, современные ОС пользуются двумя – нулевым и третьим. На нулевом уровне можно выполнять любые команды, на третьем – ограниченный набор команд. В Intel организуется защита по привилегиям.

ОС проверяет: 1) достаточно ли программа привилегированна, чтобы выполнять данную команду; 2) достаточно ли программа привилегированна, чтобы обращаться к данным других программ; 3) достаточно ли программа привилегированна, чтобы передать управление другим программам.

  1. Средства защиты памяти: защита по уровням привилегий, привилегированные команды и команды, чувствительные к уровням привилегий). Поддержка в Intel.

Привилегированные команды и команды, чувствительные к уровням привилегий.

Привилегированные: исполняются только на нулевом уровне {1) hlt – остановка ЦП;2) lgdt, lidt, lldt – загрузка регистров дескрипторных таблиц}

Не привилегированные: Могут исполняться на любом уровне. Флаг IOPL (регистр флагов) показывает, разрешено ли им выполняться. Значение IOPL можно менять только на нулевом уровне {1) cli – запрещение прерываний;

2) sti – разрешение прерываний; 3) in, out – работа с портами}

  1. Статическая и динамическая компоновка программ: определение, сравнение и примеры.

Компоновка программ и загрузка на выполнение (компоновка = связывание).

1. Отдельно оттранслированные программные модули связываются в одну программу; 2. Выполняется привязка к памяти, то есть настройка адресов. Можно выполнить компоновку и загрузку в памяти на выполнение как две отдельные задачи – в ОС есть две утилиты для решения этих задач: компоновщик (редактор связей) и загрузчик. Загрузчик выполняет загрузку программы в память на выполнение и дополнительно выполняет настройку адресов. Другой вариант – использование связывающих загрузчиков – то есть программ, которые в процессе загрузки на выполнение устанавливают связи между модулями. Связывание может быть динамическим и статическим. При статической компоновке все ссылки между программными модулями разрешаются до начала выполнения программы. Результат статического связывания – исполнимый программный модуль с простой структурой. Весь программный код, все данные, которые используются в программе, подключены к этому программному модулю. Плюс – отсутствие накладных расходов на поиск адресов, на разрешение ссылок. Минус – неэффективное использование ресурса, в частности память – один и тот же код для стандартных процедур дублируется многократно. Также недостаточная гибкость для настройки, для переработки программ – при изменении какой-либо стандартной функции нужно редактировать все программы, которые ее используют.

Статическая компоновка.

Упрощенная структура объектного модуля.

Объектный модуль имеет фиксированный формат. Он состоит из записей определенных типов. sign – это поле содержит признак формата записи. В зависимости от знака определяется остальные поля (как записи с вариантной частью). sign=T (title) – заголовок объектного модуля (name – имя объект модуля или программной секции; size – размер памяти, которая требуется для загрузки объектного модуля; ...), sign=B (body, записей типа В может быть несколько) – тело об мод (code – собственно код, содержащейся в этой записи, получен в результате трансляции; size – сколько места занимает этот конкретный код этой записи), sign=D (Definishion) – определение, описывают объекты (точки входа в процедуры; переменные, которые должны быть доступны извне), но их описание содержится в этом модуле (name – имя объекта – процедура, функция, глобальная переменная или константа); addr – адрес объекта внутри этого объектного модуля, в котором он описан; ...), sign=R (reference) – внешняя ссылка – на объект, описанный вне этого программного модуля (name – имя, соответствует этой внешней ссылке; addr – адрес ссылки на внешний объект,

которую нужно будет сформировать при компоновке – код команды есть, а параметры сформировать не смогли), sign=M – модификаторы – содержат адреса тех полей в программе (адресных констант), которые должны быть настроены при компоновке программы и при загрузке

ее на выполнение с учетом конкретного размещения этого программного модуля в памяти (...//будем считать, что при модификации полей все они настраиваются одинаково в нашем упрощенном варианте, а именно к адресу, который содержится в этом поле, полученному при трансляции, будем прибавлять адрес начала загрузки этого программного модуля на выполнение), sign=E - end – конец программного модуля (addr – адрес точки входа в программу, это поле не обязательно, может быть пустым, это точка входа для процедуры main – только для того модуля, где она находится.

Схема включения записей в объектный модуль.

П ринцип работы связывающего загрузчика (рассмотрим двухпроходный).

П ри компоновке программные секции могут содержаться в нескольких файлах. Пусть каждая программная секция записана в отдельном файле, объектном модуле (нет библиотек). Список этих файлов может быть получен компоновщиком различными способами. Например, имена могут быть перечислены как параметры в командной строке. Externel Symbols Dictionary (ESD) – словарь внешних символов, включений записи слова формата: name – имя объекта, который может быть доступен из различных программных секций, различных программных модулей (D); addr – адрес, по которому описываемый объект будет размещаться в памяти во время выполнения. Будем считать, что это абсолютный адрес относ начала памяти; ... – дополнительная информация, определяемая типом объекта {конец описания записей ESD}. Для формирования этого адреса в ходе 1-го прохода нужно знать адрес загрузки на выполнение соответствует программной секции.

Алгоритм выполнения первого прохода.

begin {start – это адрес начальной загрузки программы, то есть адрес, по которому программа запускается на выполнение} start <- запрос адреса у ОС (диспетчер памяти); {с – стек адрес, для загрузки очередного объектного модуля} c<-start; while не закончился список проверенных секций do begin {открыть файл с программной секцией} open(R,очередной файл); while есть записи do begin {читаем очередную запись} read(CR,R);{CR – первичная, в которую считывается запись – запись с вар-ми, CL – длина стека программной секции} if CR.sign<>T then {ошибка: нет заголовка об мод; завершение компоновки;}else CL<-CR.size; read(CR,R); while не конец записи do begin if CR.sign=D then if CR.name найдено в ESD then {ошибка: повторно определенное имя; завершение компоновки}else {RESD – переменная типа запись для формирования записи в словаре ESD}begin RESD.name<-CR.name; RESD.addr <-CR.addr+c{адрес для 1-й равен start}; включить RESD в ESD;end; end; end; if CR.sign<>E {запись завершения}then {ошибка: нет конца об мод; завершение компоновки}C<-CL; end; {конец 1-го прохода}

Алгоритм выполнения 2-го прохода (выполняется, если в 1-м не было ошибок.begin {beginex – на адрес, с которого начинается выполнение программы, адрес 1-й команды} beginex<-start{для com-файла, для exe beginex<-точка входа из одной из записей типа Е; такая запись должна быть одна, начальное значение может быть пустым}; begin open(R,очередной объектный модуль); read(CR,R); CL<-CR.size; CB<-C; while есть записи do begin read(CR,R); case CR.sign B: begin записать по адресу CB – CR.code; CB<-CB.size; end; R: begin if CR.name не найдено в ESD then {ошибка: неразрешенная внешняя ссылка; завершение компоновки}else begin считать в RESD найденную запись; занести значение RESD.addr по адресу CR.addr+C; end; end; M: begin увеличить значение поля по адресу CR.addr на C; end; E: begin if CR.addr<>пусто then if beginex <> start then {ошибка: несколько точек входа в главную процедуру; завершение компоновки;} else beginex<-CR.addr+C; end; end case; end{цикла по записям}; C<-C+CL; end; end. Передать управление по адресу beginex (после завершения 2-го прохода).

Управление памяти ms-dos

Оперативная память Физическая память в компьютере с традиционной архитектурой имеет линейную организацию, то есть представляет собой линейный "массив", состоящий из ячеек одинаковой длины. Базовой единицей данных для всех современных процессоров является 1байт 0 (byte), который представляет собой 8 разрядных ячеек памяти, разряды которые нумеруются справа налево от 0 до 7. При этом правые разряды называются младшими, а левые - старшими. В каждом разряде может быть записано значение 0 или 1, такую величину называют  1битом. Таким образом, 1байт это набор из 8 битов, то есть последовательность из 8 нулей и единиц. Байты (ячеек памяти) нумеруются от 0, и порядковый номер байта называется его адресом.

ПК на базе процесс. Intel позволяет адресовать также слова и двойные слова (для последних процессоров семейства).

Слово состоит из 2 соседних байтов. Разряды слова также нумеруются справа налево от 0 до 15. Адресом слова считается адрес его младшего байта. Двойное слово(double word) - это уже четыре соседних байта, а разряды в нем нумеруются от 0 до 31.

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

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

Однако не всегда при написании программы существует возможность распределять всю память, необходимую для выполнения программы. Возникнет необходимость сохранения некоторых промежуточных результатов, распределенных памятью для параметров подпрограммы и ее данных при вызове. В этом случае используется динамическое распределение памяти. Существует два основных способа организации памяти, распределенной динамически: организованная память в виде стека и "кучи". " Куча " (Heap) область память, используемая для размещения данных в ходе выполнения программы. Доступ к данным в "куче" осуществляется произвольным образом - указываем их адресов. То есть возникает необходимость запоминание адресов (или указателей) динамически размещенных данных. Указатель также сохраняется в памяти, поэтому при использовании "кучи" для размещения данных обычно формируются списки. Стек (Stack) также используется для динамически размещенных данных, но, в отличии от кучи, доступ к данным в область памяти, организована в виде стека, осуществляется с одного конца этой области, называемой вершиной стека, то есть элемент, записывается в стек последним, выбирается из него первым. Таким образом, для работы со стеком определены две основные операции: вставка элемента в вершину стека (или операция проталкивания) и удаление элемента из вершины стека (выталкивание).

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

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

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

Понятие динамической компоновки, организация DLL. В этом случае разрешение ссылок откладывается либо на момент загрузки программы, либо на время ее выполнения. Существует 2 случая динамической компоновки: явная (во время выполнения) и неявная (в момент загрузки). I) Для неявного случая, при разработке библиотеки, программист должен с помощью специальных директив дать указания (которые перейдут компоновщику) транслятору, о том, какие объекты должны быть доступны извне. Из этой информации в заголовок библиотеки будут включены записи, аналогичные записям-определителям (секция Exports, в ней экспортируем имена). У загружаемого исполнимого модуля, использующего библиотеки, в заголовке должна быть сформирована таблица импорта, подобная записи внешних ссылок (R). Порядок поиска библиотеки: 1). В папке, где находиться exe-файл. 2). Windows\system\… и в текущей папке. 3).По переменной окружения PATH. Основной недостаток такого способа – при отсутствии хотя бы одной функции программа не будет запускаться на выполнение, даже если эта функция не используется. II). Для явной компоновки загрузка DLL отодвигается по времени до момента, когда функции будут использоваться в программе. При запуске исполнимого модуля экономится объем дисковой памяти, потому что код программы из exe не переписывается в pagefile.