Защищенный режим

 

Оглавление: 
 
 

Максимальный  режим работы ЦП. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

     Введение. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2

     Уровни  привилегий. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3

     Адресация памяти в защищенном режиме. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

     Работа  прерываний. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7

     Список  литературы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8

Компиляция  и отладка ассемблерных программ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

     Общие сведения о языке ассемблера. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

     Процесс разработки программы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

     Компиляция  программы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

     Отладка программы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13

     Список  литературы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14 
 

 

максимальный  режим работы ЦП. 

Введение 

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

Процессоры могут  работать в различных режимах. Под  термином «режим» подразумевается способы, которым процессор создает (и обеспечивает) для себя рабочую среду. Режим работы процессора задает способ адресации к оперативной памяти и способ управления отдельными задачами. Процессоры персональных компьютеров могут работать в трех режимах: реальном, защищенном и виртуальном режимах. 

Реальный  режим 

Первоначально персональные компьютеры фирмы IBM могли  адресовать только 1 Мбайт оперативной  памяти. Это решение, принятое в начале развития персональных компьютеров, продолжало соблюдаться и в последующее  время — в каждом компьютере следующего поколения процессор должен был  уметь работать в режиме совместимости  с процессором Intel 8086. Этот режим назвали реальным. Когда процессор работает в реальном режиме, он может обращаться к памяти только в пределах 1 Мбайт (как и процессор Intel 8086), и не может использовать 32-разрядные и 64-разрядные операции. Процессор попадает в реальный режим сразу же после запуска. В реальном режиме работают операционные системы DOS и стандартные DOS-приложения. 

Защищенный  режим 

Начиная с процессоров  Intel 80286 и компьютеров типа IBM PC/AT, появляется защищенный режим. Это более мощный режим работы процессора по сравнению с реальным режимом. Он используется в современных многозадачных операционных системах.  

Защищенный  режим имеет много  преимуществ: 

■ В защищенном режиме доступна вся системная память (не существует предела 1 Мбайт).

■ В защищенном режиме операционная система может организовать одновременное выполнение нескольких задач (многозадачность).

■ В защищенном режиме поддерживается виртуальная память — операционная система при необходимости может использовать жесткий диск в качестве расширения оперативной памяти.

■ В защищенном режиме осуществляется быстрый (32/64-разрядный) доступ к памяти и поддерживается работа 32-х разрядных операций ввода-вывода. 

Каждая выполняемая  на компьютере программа имеет свою собственную область памяти, которая  защищена от доступа со стороны других программ. Когда какая-либо программа  пытается обратиться по неразрешенному для нее адресу памяти, генерируется ошибка защиты памяти. Все современные  операционные системы используют защищенный режим, включая Windows 98/Ме, Windows NT/2000/XP, OS/2 и Linux. Даже операционная система DOS (обычно работающая в реальном режиме) может использовать доступ к памяти защищенного режима с помощью программного интерфейса DPMI (DOS Protected Mode Interface — интерфейс защищенного режима операционной системы DOS). Этот интерфейс используется компьютерными играми и другими программами под DOS для того, чтобы преодолеть барьер в 640 Кбайт основной памяти DOS. С появлением процессора Intel 386 защищенный режим был усовершенствован: увеличено максимально доступное адресное пространство, расширена система команд. Поэтому он иногда называется усовершенствованным защищенным режимом.

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

Виртуальный режим 

Защищенный режим  используют графические многозадачные  операционные системы, такие как  Windows. Иногда возникает необходимость выполнения DOS-программ в среде операционной системы Windows. Но DOS-программы работают в реальном режиме, а не в защищенном. Для решения этой проблемы был разработан виртуальный режим или режим виртуального процессора 8086. Этот режим эмулирует (имитирует) реальный режим, необходимый для работы DOS-программ, внутри защищенного режима. Операционные системы защищенного режима (такие как Windows) могут создавать несколько машин виртуального режима — при этом каждая из них будет работать так, как будто она одна использует все ресурсы персонального компьютера. Каждая виртуальная машина получает в свое распоряжение 1 Мбайтное адресное пространство, образ реальных программ BIOS и т.п. Виртуальный режим используется при работе в DOS-окне или при запуске DOS-игр в операционной системе Windows 98/Ме. При запуске на компьютере DOS-приложения операционная система Windows создает виртуальную DOS-машину, в которой выполняется это приложение. 
 

Уровни  привилегий. 

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

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

Простейшие  уровни привилегий, реализованные в ЭВМ 60-х годов - это работа в режимах пользователя (User) и системы, или супервизора (Supervisor). Эта двухуровневая модель хорошо зарекомендовала себя в системах, когда одна большая ЭВМ (операционная система, процесс и т.п.) обслуживала нескольких равноправных пользователей. Двухуровневая система привилегий работает на компьютерах Apple Macintosh вплоть до настоящего времени и в микропроцессорах x86 при страничной организации памяти.

С появлением современных  технологий работы вычислительной техники (технологии Клиент-сервер, "тонкие" клиенты, Jini и т.п.) двух уровней привилегий стало не хватать. Предвосхищая эту проблему, фирма Intel предложила в своем процессоре i80386 четырехуровневую систему привилегий на уровне сегмента.

В этой системе  четыре уровня и они имеют номера от 0 до 3. Уровень номер 0 - самый верхний - программе на этом уровне "можно всё". Уровень 1 – следующий в иерархии и запреты, установленные на уровне 0, действуют для уровня 1. Наконец, 3-ий уровень - имеет самый низкий приоритет. 

 Оптимальная схема работы программ по уровням привилегий будет следующая: 

уровень 0: ядро операционной системы,

уровень 1: драйверы ОС,

уровень 2: интерфейсы ОС,

уровень 3: прикладные программы. 

На  каждом уровне привилегий проверяется: 

Может ли программа  выполнить указанную подпрограмму?

К данным каких программ может обратиться та или иная программа?

Имеет ли программа  право передавать управлению внешнему процессу и какому именно? 

Накладываемые ограничения: 

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

2. Программам  не разрешается считывать/записывать  элементы данных, которые имеют  более высокий уровень привилегий. Однако программы могут использовать  данные на своем и более  низком уровне привилегий.

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

Сам по себе уровень  привилегий ещё ничего не значит, его  нельзя "установить в процессоре". Уровень привилегий применяется как одно из свойств при описании различных объектов, например, программного сегмента и действует при работе только с этим объектом. Уровень привилегий обозначается как "PL" (от Privilege Level) и применяется в сочетаниях, например, IOPL – Input-Output Privilege Level - уровень привилегий ввода-вывода. 

Адресация памяти в защищенном режиме. 

Сегментом называется условно выделенная область адресного пространства определённого размера, а смещением — адрес ячейки памяти относительно начала сегмента.

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

Адресация памяти в защищенном режиме также производится через сегмент и смещение в сегменте, для чего используется пара регистров, но для описания сегмента используется больше информации, а именно: 

  • 32-разрядный  адрес,
  • 20-разрядный предел сегмента (предел = размер - 1),
  • номер уровня привилегий сегмента,
  • тип сегмента (программный, стек, данные или системный объект)
  • и некоторые дополнительные свойства
 

 Для того, чтобы хранить эту информацию, используется специальная область памяти. Сегмент по-прежнему указывается в сегментном регистре, но теперь в нём хранится номер сегмента из списка определённых сегментов. Этот номер называется селектор. В качестве смещения используется 16- или 32-разрядный регистр. При обращении к памяти, процессор проверяет возможность доступа к сегменту по уровню привилегий, проверяет, не превысил ли адрес предел сегмента и можно ли обращаться к этому сегменту в данном случае (например, запрещена передача управления в сегмент, описывающий данные или стек). Если в результате проверки будет обнаружено нарушение какого-либо условия, то процессор сгенерирует исключение и тем самым обеспечит защиту. 

Предел  сегмента - это максимально допустимое смещение внутри него, таким образом, предел сегмента определяет его размер: размер_сегмента = предел_сегмента + 1. Поскольку значение предела - 20-разрядная величина, это значит, что максимальное значение предела равно 220 - 1. Процессор измеряет размер сегмента двумя типами величин: либо байтами, либо страницами. Страница - это блок памяти размером в 4Кб. В описании сегмента можно указать, в каких единицах измеряется сегмент и тогда можно получить два типа сегментов с максимальными размерами:

·  в 1Мб ( 2 20 байт ) или

·  в 4Гб ( 2 20 страниц = 2 20 * 4Кб = 2 20 * 2 12 = 2 32 байт )

Эта способность  измерять сегмент либо байтами, либо страницами, называется  гранулярность.  Значение предела сегмента может быть любым, от 0 до 2 20 - 1, гранулярность устанавливается по усмотрению программиста и может быть либо байтная, либо страничная. Всё это позволяет определять сегменты любого размера - от 0 байт до 4Гб. 

Сегмент определяется в виде структуры данных, которая  называется дескриптор. Размер дескриптора - 8 байт, все дескрипторы хранятся последовательно в специально отведённой области памяти - глобальной дескрипторной таблице. На рис.1. приведен формат структуры дескриптора. 

Рис.1. Структура дескриптора 

Значения предела  и адреса сегмента "разбросаны" по всей структуре дескриптора потому, что впервые защищённый режим появился в 16-разрядном процессоре Intel 80286 и для совместимости с ним дескриптор не переделывали, а расширили дополнительными полями (биты с 49 по 63). Практически, в программах формат дескриптора удобнее использовать в следующем виде: 

descriptor:           

 dw       limit_low                      ; младшее слово предела           

 dw       address_low                 ; младшее слово адреса           

 db        address_hi                    ; 3-й (из четырёх) байт адреса           

 db        access_rights                ; права доступа           

 db        limit_hi_and_flags       ; старшая часть предела и флаги           

 db        address_hi                    ; 4-й байт адреса

Байт прав доступа (40-47) имеет следующий формат:  

   40: A – бит доступа (Accessed)

     41-43: Тип сегмента (табл.1)  

   44: S – бит системного сегмента (System)

     45-46: DPL – уровень привелегий (Descriptor Privelege Level )    

 47: P – бит присутствия (Present) сегмента в ОЗУ           

                                                                                            

Таблица 1

Тип Назначение  сегмента
000 Сегмент данных только для чтения
001 Сегмент данных для чтения и записи
010 Сегмент стека  только для чтения
011 Сегмент стека  для чтения и записи
100 Сегмент кода с  разрешением только выполнения
101 Сегмент кода с  разрешением выполнения и чтения из него
110 Подчиненный сегмент  кода с разрешением выполнения
111 Подчиненный сегмент  кода с разрешением выполнения и  чтения из него
 

Тетрада флагов (52-55) G,D,X,U имеет формат:  

 

   52: бит U – пользователь (User)  

53: бит X –  зарезервирован  

54: бит D –  размерность (Default size) операндов  

55: бит G –  бит гранулярности (Granularity) 

При адресации  памяти в защищённом режиме команды  ссылаются на сегменты, указывая не их адреса (как в режиме реальных адресов), а описания сегментов (их дескрипторы). Указатель на описание сегмента называется селектор. Другими словами, селектор - это номер дескриптора из таблицы дескрипторов. Адресация производится через пару регистров сегмент:смещение, причём, в качестве сегментного регистра используются обычные CS, SS, DS, ES, FS и GS (последние два появились в ЦП Intel 80386), но в них указывается не адрес сегмента, а селектор дескриптора.  

Селекторы нужны, по крайней мере, по трём причинам: 

  1. Описание  сегмента занимает 8 байт и использовать 8-байтные сегментные регистры было бы крайне неэффективно.
  2. Селекторы имеют размер в 16 бит, благодаря чему их можно использовать в сегментных регистрах и обращаться к памяти можно по-прежнему через пару регистров.
  3. Параметры всех сегментов хранятся в отдельной области памяти, доступ к которой имеет только операционная система. Программа, используя селектор, сможет получить о сегменте совсем немного информации и не сможет изменить параметры сегмента, благодаря чему очень удачно реализуется механизм защиты
 

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

Селектор имеет  следующий формат: 

     Рис. 2. Формат селектора. 

Двухбитовое поле RPL (Requested Privilege Level) содержит номер уровня привилегий, которое имеет текущая программа. Значение этого поля процессор использует для защиты по привилегиям. К одному и тому же дескриптору можно обращаться, используя селекторы с разными значениями RPL, но процессор позволит доступ только при определённых условиях.

Бит TI (Table Indicator) определяет таблицу, из которой выбирается нужный дескриптор. Если бит TI = 0, то обращение производится к глобальной дескрипторной таблице GDT (она одна на всю систему), если TI = 1 - то к текущей локальной дескрипторной таблице LDT (таких может быть много).

Index - это собственный номер дескриптора, от 0 до 8191. Так как поле индекса состоит из 13 бит, то максимальное число дескрипторов, одновременно существующих в системе равно 2 13, т.е. 8192. Это довольно-таки много и вполне удовлетворяет любым системным запросам. На самом деле, число дескрипторов можно значительно увеличить за счёт использования множества дополнительных локальных дескрипторных таблиц. 

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

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

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

Работа  прерываний 

В защищённом режиме работа прерываний происходит следующим образом:       

Во-первых, вводится новый класс прерываний, генерируемых самим процессором при нарушениях условий защиты - так называемые исключения (exceptions). Число возможных вектором прерываний по-прежнему равно 256, но 32 из них - от 00h до 1Fh используются исключениями.

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

В-третьих, сама таблица прерываний, которая называется IDT (Interrupt Descriptors Table), может находится по любому адресу памяти.

Все эти особенности  появились в процессоре Intel80386 и  в полном объёме, с небольшими дополнениями, используются во всех 32-разрядных процессорах. Прерывания с векторами от 00 до 1Fh, т.е. исключения - это основа защищённого режима. Благодаря исключениям процессор автоматически реагирует на любые попытки нарушить защиту системы и позволяет их корректно обработать. Благодаря разделению кода и данных по уровням привилегий, обработчики прерываний можно надёжно изолировать от других программ.  В грамотно построенной операционной системе никакая программа не сможет перехватить прерывание, изменить код или даже просто прочитать его, выйти за предел отведённых ей адресов и пр. Благодаря исключениям, операционная система может контролировать любые нарушения условий, поставленных ею. Когда срабатывает прерывание, процессор должен передать управление соответствующей процедуре-обработчику. В режиме реальных адресов это происходит сразу - из памяти выбирается вектор и по dw:dw адресу происходит переход. В защищённом режиме ситуация обстоит сложнее - перед передачей управления процессор производит множество проверок возможности доступа к обработчику прерывания - обеспечивает защиту. 

Адрес, по которому произойдёт переход на обработчик прерывания, находится в дескрипторе прерывания. Каждому вектору прерыванию соответствует свой дескриптор, все они (до 256) объединяются в специальную таблицу дескрипторов прерываний (IDT) и по формату похожи на дескрипторы сегментов. 
 
 
 
 
 
 
 

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

    1. http://dgs-srl.com/evmt5.html
    2. http://citforum.ru/hardware/memory/mem_0505.shtml
    3. Г.В. Орловский "Введение в архитектуру микропроцессора 80386", Санкт-Петербург, 1992 г.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Компиляция  и отладка ассемблерных программ.

Общие сведения о языке  Ассемблера.

Машинный  язык – это комбинации, в виде строго организованных последовательностей нулей и единиц. Таким образом, внешне являясь полиглотом, компьютер понимает только один язык — язык машинных команд.

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

Символические имена, вводимые при программировании на языке ассемблера, как правило, отражают семантику программы, а  аббревиатура команд – их основную функцию.

Например:  

PARAM – параметр;

TABLE – таблица;

MASK – маска;

ADD – сложение;

SUB – вычитание;

MUL – умножение 

Язык ассемблера позволяет эффективно писать и отлаживать значительно более сложные программы, чем машинный язык (до 1 - 4 Кбайт ).

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

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

В связи с  этим практически все программы  управления устройствами ввода/вывода (драйверы ) пишутся на языке ассемблера не смотря на наличие достаточно большой номенклатуры языков высокого уровня. 

С помощью языка  ассемблера программист может задать следующие параметры: 

  1. мнемонику ( символическое имя ) каждой команды машинного языка микропроцессора;
  2. стандартный формат для строк программы, описываемой на ассемблере;
  3. формат для указания различных способов адресации и вариантов команд;
  4. формат для указания символьных констант и констант целочисленного типа в различных системах счисления;
  5. псевдокоманды, управляющие процессом ассемблирования (трансляции) программы.

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

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

Каждая строка написанной на языке ассемблера программы  содержит четыре поля:

МЕТКА КОД ОПЕРАНД КОММЕНТАРИЙ 

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

Защищенный режим