Организация ЭВМ и периферийные устройства
Выбери формат для чтения
Загружаем конспект в формате docx
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
МИНИСТЕРСТВО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
ЮЖНЫЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ
В.Ф. ГУЗИК, В.А. КАЛЯЕВ, А.И. КОСТЮК
Организация ЭВМ и периферийные устройства
Учебное пособие
УДК 681.3(075.8)+681.324(075.8)
Гузик В.Ф., Каляев В.А., Костюк А.И. Организация ЭВМ и систем: Учебное пособие.
Таганрог: , 116 с.
Данное учебное пособие представляет собой конспект лекций по курсу «Аппаратные средства вычислительной техники». Целью курса является подробное знакомство студентов с особенностью организации современных микропроцессоров, ЭВМ и ПЭВМ, освоение ими аппаратных и аппаратно-программных решений, используемых при создании подсистем и узлов вычислительных устройств.
Табл. 26. Ил. 87. Библиограф: 14 назв.
Р е ц е н. з е н т ы:
1. Таганрогский НИИ Связи, ведущий сотрудник ТНИИС А.В. Маргелов, д.т.н., с.н.с.
2. Н.И. Витиска, д.т.н., проф., проректор по УР ТГПИ.
1. ЭВМ ОБЩЕГО НАЗНАЧЕНИЯ
1.1 Структура ЭВМ общего назначения.
Любая ЭВМ содержит два основных блока:
• центральный процессор (ЦП);
• оперативную память (ОП).
Задачей ЦП является выполнение машинных команд, которые он выбирает из ОП. Внутренняя организация различных ЦП может серьезно отличаться друг от друга, однако любой ЦП содержит ряд стандартных блоков. К ним относятся:
• дешифратор команд, позволяющий декодировать считанную из ОП команду;
• арифметико-логическое устройство (АЛУ), позволяющее реализовать заданную в команде операцию;
• блок регистров общего назначения (блок РОН), предназначенных для временного хранения информации. Наличие РОН позволяет резко снизить количество обращений к ОП, повышая тем самым общее быстродействие ЭВМ;
• устройство управления (УУ), обеспечивающее на всех этапах выполнения команды выработку необходимых управляющих сигналов.
Оперативная память состоит из ПЗУ и ОЗУ и предназначена для хранения программ, исходных данных, а также промежуточных и конечных результатов вычислений.
Обычно ЭВМ общего назначения организуется по так называемой схеме с общей шиной (рис. 1).
Здесь ВУ – внешнее устройство.
Системная шина (СШ) в свою очередь подразделяется на шину адреса (ША), шину данных (ШД) и шину управления (ШУ). На ША процессор выставляет адреса ячеек памяти и портов внешних устройств, к которым он обращается. На шине управления процессор формирует сигналы, управляющие передачей информации. Сама передача информации производится по ШД.
В любой конкретный момент времени к СШ может быть подключено не более двух устройств. Одно из этих устройств передает информацию, другое ее принимает. Как правило, одним из этих устройств является ЦП, который и управляет передачей информации по шине. Исключением является режим прямого доступа к памяти, когда ЦП в обмене участия не принимает, а управление обменом берет на себя стоящий в системе контроллер прямого доступа к памяти.
1.2 Арифметико-логические устройства.
АЛУ выполняет операции по преобразованию поступающей в него информации. В машинах малой и средней мощности, не имеющих отдельного блока для формирования физических адресов ОП, на АЛУ также возлагаются операции адресной арифметики.
Алгоритмы операций, выполняемых на АЛУ, включают определенную последовательность элементарных действий (микроопераций), среди которых различают прием кода операнда, преобразование этого кода, суммирование кодов двух операндов, сдвиг кода, логические операции над кодами и ряд других.
Для выполнения этих действий в АЛУ в общем случае включаются следующие функциональные узлы:
• регистры для временного хранения операндов;
• сдвигатели;
• преобразователи прямого кода в дополнительный и обратно;
• сумматор, на котором реализуются арифметические и логические операции.
Существует много различных типов АЛУ. Например, по системам счисления различают АЛУ с двоичной и десятичной арифметикой, по формам представления числовых данных–АЛУ с фиксированной и плавающей запятой и. т. д. Более подробные сведения о типах и структурах АЛУ рекомендуется искать в соответствующей литературе.
1.3 Устройства управления.
Каждая машинная команда требует в общем случае для своей реализации несколько машинных тактов. В каждом такте УУ должно обеспечить выдачу необходимого набора управляющих сигналов. Такой набор управляющих сигналов принято называть микрокомандой, а последовательность микрокоманд, необходимую для выполнения какой-либо машинной команды – микропрограммой этой команды
Существует два основных способа построения логики управляющего устройства:
• Устройство с «жесткой логикой». Здесь для каждой реализуемой в процессоре операции строится набор схем, которые в нужных тактах возбуждают соответствующие управляющие сигналы.
• Микропрограммное устройство управления. Здесь все необходимые микропрограммы хранятся в памяти (как правило, в ПЗУ) в виде последовательностей микрокоманд. Любая микрокоманда при этом несет в себе информацию обо всех вырабатываемых в данном такте управляющих сигналах и об адресе следующей микрокоманды.
В настоящее время УУ с «жесткой логикой» используются довольно редко. Связано это, например, с тем, что любые изменения в системе команд приводят к переделке УУ с «жесткой логикой», в то время как для микропрограммного УУ в этом случае достаточно будет перепрограммировать ПЗУ.
Типичная структура микропрограммного УУ приведена на рис. 2
Рис. 2
Работа схемы осуществляется следующим образом. Из ОП считывается очередная машинная команда. Код операции этой команды дешифрируется и подается на устройство формирования адреса микрокоманд. Последнее вырабатывает адрес первой микрокоманды соответствующей микропрограммы. Эта микрокоманда считывается из памяти и помещается в регистр микрокоманд. Операционная часть микрокоманды дешифрируется (в общем случае!) и соответствующие управляющие сигналы подаются на АЛУ (вернее на операционный блок). Адресная часть микрокоманды определяет адрес следующей микрокоманды. Также в процессе формирования адреса следующей микрокоманды могут принимать участие и снимаемые с АЛУ признаки (например, признак «нулевого результата» и другие подобные). Эти признаки позволяют организовывать в микропрограммах условные переходы. Последняя микрокоманда микропрограммы несет в себе информацию о том, что она является последней и, следовательно, можно считывать из ОП следующую машинную команду.
В зависимости от способа формирования управляющих сигналов различают горизонтальное, вертикальное и смешанное микропрограммирование. При горизонтальном микропрограммировании каждый разряд кода микрооперации микрокоманды (смотри рис. 2) ставится в соответствие одному из возможных управляющих сигналов или, что то же самое, одной из возможных микроопераций. Если в разряде стоит единица, то соответствующая микрооперация в данном такте выполняется, если ноль – нет. При таком способе операционная часть микрокоманды содержит m разрядов, где m – общее число микроопераций в процессоре.
Достоинством такого способа является возможность одновременного выполнения в одном такте любого набора микроопераций и простота формирования управляющих сигналов. Последние просто снимаются из соответствующих разрядов микрокоманды. При этом, указанный на рис. 2 дешифратор оказывается не нужен. Однако у этого способа имеется и очевидный недостаток, а именно, при большом числе управляющих сигналов (а зачастую их число достигает нескольких сотен) формат микрокоманды становится недопустимо большим. В этом случае предпочтительнее использовать вертикальное микропрограммирование.
При вертикальном микропрограммировании код микрооперации в микрокоманде задает одну из микроопераций. Длина операционной части микрокоманды при этом значительно сокращается и составляет log2m, однако, такая микрокоманда требует дешифрации. Кроме того, при таком способе невозможно задать в одном такте более одного управляющего сигнала, что, очевидно, снижает быстродействие процессора.
В настоящее время наибольшее распространение имеет смешанное микропрограммирование, в котором сочетаются методы горизонтального и вертикального микропрограммирования. Например, можно разбить все микрооперации на группы и внутри любой группы использовать вертикальное, а между группами – горизонтальное микропрограммирование.
1.4 RISC и CISC процессоры.
Начиная с 50-х годов и до середины 80-х развитие процессоров шло по традиционному пути. Архитектура процессоров усложнялась в основном за счет развития технологии, а не за счет принципиально новых идей. Система машинных команд таких процессоров также постоянно усложнялась, что было обусловлено стремлением, обеспечить поддержку новых сложных языков высокого уровня (ЯВУ). Все разработанные за этот период времени процессоры относятся к типу CISC (common instruction set computer – «процессор с полным набором команд»). В середине 80-х этот путь развития был поставлен под сомнение, что привело к появлению RISC – процессоров (reduce instruction set computer – «процессор с сокращенным набором команд»). Рассмотрим далее причины, которые привели к этому повороту.
По мере того как стоимость аппаратной части CISC – процессоров уменьшалась, увеличивались затраты на программное обеспечение. Помимо высокой стоимости и неудобств в использовании, к недостаткам программного обеспечения относится наличие элемента ненадежности: для всех программ характерно выявление все новых и новых ошибок даже после нескольких лет эксплуатации. Фирмы решали эту проблему путем создания все более сложных ЯВУ, которые помогали программистам избегать ошибок. Однако, этот подход породил другую проблему –«семантический разрыв». Проблема заключается в существенном различии между операторами ЯВУ и машинными командами процессоров. Таким образом, этот разрыв привел к неэффективному выполнению операторов, чрезмерному объему программ и большой сложности компиляторов. Пришлось искать архитектурные решения, направленные на устранение этого разрыва.
К основным особенностям CISC архитектур относятся:
• использование сложных машинных команд;
• большое число используемых способов адресации;
• аппаратная реализация некоторых операторов ЯВУ.
Эти особенности, как предполагается, способствуют достижению следующих целей:
• облегчить труд разработчиков компиляторов;
• повысить эффективность выполнения операторов;
• обеспечит базу для использования гораздо более изощренных ЯВУ.
В конце концов, такой подход породил сомнения у некоторых разработчиков, и они провели исследование и анализ программ, написанных на ЯВУ. При этом выяснилось, что 2/3 операторов составляют простейшие операторы вида А=В. Был сделан вывод, что подгонка системы команд под ЯВУ не самая лучшая стратегия. Гораздо более эффективным может оказаться путь оптимизации наиболее часто встречающихся в программах операторов.
Обобщение этих и других исследований привело к тому, что были сформулированы три принципиальные особенности архитектуры RISC – процессоров:
• использование большого числа (до нескольких сотен) внутренних регистров, с целью снижения числа обращений к ОП;
• использование эффективного конвейера команд, эффективность которого обеспечивается простотой форматов машинных команд;
• использование сокращенного набора машинных команд, что и позволяет использовать простые форматы машинных команд.
Существует много подходов к построению RISC – процессоров, однако у них у всех есть общие характеристики:
• Одна машинная команда выполняется за один машинный цикл. Это позволяет реализовать большинство машинных команд аппаратным образом и, следовательно, обеспечить более высокое быстродействие, по сравнению с CISC – процессорами, где большинство команд требуют использования микропрограмм.
• Большинство операций имеют тип «регистр-регистр». Это позволяет упростить УУ и тем самым повысить быстродействие.
• Используются только простые способы адресации. Это можно считать и достоинством и недостатком, так как формат команды упрощается, но более сложные способы адресации приходится организовывать программно.
• Простые форматы машинных команд. Обычно используется один или несколько (два-три) формата. При этом все команды имеют фиксированную длину и фиксированное расположение полей. Такой подход дает возможность легко реализовать конвейер команд, упростить УУ и, в конечном итоге, повысить быстродействие процессора.
Выпускаемые в настоящее время процессоры сочетают в своей архитектуре особенности RISC и CISC процессоров.
1.5 Форматы машинных команд.
Машинной командой называется двоичное слово, содержащее всю информацию, необходимую процессору для выполнения заданной операции. А именно:
• тип операции;
• адреса операндов;
• адрес приемника результата.
Для фиксации этой информации в машинной команде выделяются группы разрядов, называемые полями. Любая машинная команда состоит из поля кода операций (КОП) и ряда адресных полей. Форматом машинной команды называется заранее оговоренная структура ее полей.
В наиболее общем случае машинная команда должна иметь формат, представленный на рис.3.
Рис. 3.
Здесь А1 – поле адреса первого операнда, А2 – поле адреса второго операнда, А3– поле адреса приемника результата, А4 – поле адреса следующей машинной команды. Это, так называемая, четырехадресная машинная команда.
Очевидно, что чем больше в команде полей, тем больше места занимает команда в оперативной памяти (ОП). Это в свою очередь приводит к непроизводительному расходу памяти и снижению общего быстродействия ЭВМ, так как считывание таких команд из ОП требует больших временных затрат.
На практике четырехадресные машинные команды никогда не использовались. Действительно, машинные команды любой программы располагаются в ОП не хаотично, а последовательно, одна за другой. Поэтому в состав процессора вводится специальный регистр, называемый программным счетчиком. Перед началом выполнения программы, в него заносится адрес первой команды программы. После считывания очередной машинной команды из ОП содержимое программного счетчика автоматически увеличивается на число считанных байт. Таким образом в программном счетчике автоматически формируется адрес следующей машинной команды программы. При таком подходе поле А4 становится ненужным и команда становится трехадресной.
Договоримся теперь, что результат операции мы всегда будем помещать на место одного из операндов, например первого. При этом отпадает необходимость в поле А3 и команда становится двухадресной. Хотя при таком подходе команды несколько теряют в гибкости и создаются определенные неудобства при программировании, практика показала, что выйгрыш здесь значительно превышает пройгрыш.
Иногда в состав процессора вводят специальный регистр, называемый аккумулятором, и оговаривают, что один из операндов всегда берется из аккумулятора и в него же загружается результат операции. При такой ситуации команды становятся одноадресными.
Существуют и безадресные команды, например команды, реализующие стековые операции.
В современных процессорах используются, как правило двух-, одно- и безадресные команды. Например команды микропроцессора К1810ВМ86:
• add dx, [234h] – двухадресная
• inc byte ptr [40h] – одноадресная
• push bx – безадресная.
1.6 Способы адресации.
Физическим адресом (Аф) будем называть двоичный номер ячейки памяти, к которой мы обращаемся. Адресным кодом (Ак) будем называть двоичное число, которое записано в адресном поле команды. Как правило в современных ЭВМ Ак не совпадает с Аф. Способ формирования Аф по заданному в команде Ак и называется способом (методом) адресации. Далее рассмотрим наиболее часто используемые на практике способы адресации.
1. Непосредственная адресация. В адресном поле команды задается не адрес операнда, а непосредственно сам операнд. Например, sub bl, 25.
2. Прямая адресация. В адресном поле команды задается адрес ячейки памяти. То есть в этом случае Аф = Ак. Например, mov [200h],al. Прямая адресация не дает возможности для организации циклов.
3. Косвенная адресация. Адресный код задает регистр процессора. Содержимое этого регистра берется в качестве Аф. Например, add ax, [bx]. Косвенная адресация предоставляет программисту простую возможность организации циклов.
4. Базовая адресация. Адресный код задает регистр процессора, откуда берется, так называемый, «базовый адрес», и некоторую величину, называемую смещением. Процессор вычисляет Аф путем сложения базового адреса со смещением. Например, add di, [si+100]. Базовая адресация удобна при работе с одномерными массивами. Базовый адрес при этом задает начальный адрес массива, а смещение указывает на элемент внутри массива. Кроме того, базовая адресация обеспечивает простую возможность перемещения программы в ОП без модификации этой программы.
5. Базово-индексная адресация. Адресный код задает два регистра процессора и смещение. Процессор вычисляет Аф, складывая смещение и содержимое обоих регистров. Например, mov dx, [bp+si+2]. Такая адресация удобна при работе с двухмерными массивами.
1.7 Стековая адресация. Виды стеков.
Стек – это особый вид памяти. Если при обращении к обычной памяти необходимо задавать адрес ячейки, к которой производится обращение, то при обращении к стеку адрес задавать не надо.
Различают два вида стеков:
• стек, реализующий процедуру LIFO (last input-first output -последним пришел – первым ушел);
• стек, реализующий процедуру FIFO (first input-first output - первым пришел –первым ушел).
Стек, реализующий процедуру LIFO, организуется, как правило, на обычной оперативной памяти. В состав процессора вводится специальный регистр, называемый указателем стека. Его содержимое адресует ячейку ОП, которую принято называть вершиной стека. После любой стековой операции содержимое указателя стека изменяется, соответственно меняется и вершина стека.
Например, в микропроцессорах фирмы Intel в качестве указателя стека используется регистр sp (esp). При выполнении команды push dx вначале из содержимого sp вычитается двойка и затем по полученному адресу и ОП записывается содержимое регистра dx. При выполнении команды pop bx в регистр bx выталкивается слово из вершины стека, а затем к sp прибавляется двойка.
Стек, реализующий процедуру FIFO, обычно организуется аппаратным образом на регистрах.
2. МИКРОПРОЦЕССОРНЫЙ КОМПЛЕКТ К1810
2.1 Микропроцессор К1810ВМ86.
Зарубежный аналог этой микросхемы имеет обозначение i8086.
Данный микропроцессор (МП) относится к CISC типу. Он имеет 20 адресных линий (то есть может адресовать 220 =1 Мбайт ячеек ОП) и 16 линий данных. МП может работать в двух режимах: минимальном и максимальном.
Минимальный режим используется, когда на основе МП реализуется несложная однопроцессорная система. Для сложных однопроцессорных и многопроцессорных систем используется максимальный режим.
2.2 Назначение входов/выходов ВМ86 в минимальном режиме.
Обозначение МП ВМ86 на функциональных схемах приведено на рис.4. Рассмотрим назначение входов-выходов МП в минимальном режиме.
CLK (clock – частота) – вход тактовых импульсов. Синхросерия на этот вход обычно подается с микросхемы генератора К1810ГФ84 (i8284).
INTR (interrupt request – запрос на прерывание) – маскируемый вход запросов на прерывание. Все запросы на прерывание от внешних устройств заводятся на этот вход через схему ИЛИ. Внутри процессора имеется флаг if. Если этот флаг установлен в единицу, МП воспринимает запросы на входе INTR, если установлен в ноль – игнорирует. Вход INTR называют статическим. Процессор опрашивает сигнал на этом входе на границах команд. Поэтому сигнал на этом входе должен иметь достаточную длительность, иначе процессор может его «не заметить». Эту ситуацию должен учитывать разработчик аппаратуры.
INTA (interrupt acknowledge – прерывание подтверждаю) – выход подтверждения прерывания. Если МП воспринял запрос на входе INTR, он вырабатывает два сигнала на выходе INTA, подтверждая тем самым прерывание. Эти сигналы предназначены для контроллера прерываний К1810ВН59 (i8259).
NMI (non-maskable interrupt - немаскируемое прерывание) – немаскируемый вход запросов на прерывание. МП всегда воспринимает запросы, поступающие на этот вход, независимо от состояния флага if. Сигналы подтверждения прерывания при этом не вырабатываются. Этот вход называют динамическим. Внутри процессора стоит триггер, срабатывающий по переднему фронту сигнала на входе NMI. На границах команд процессор опрашивает состояние этого триггера. Таким образом требования к длительности сигнала на входе NMI существенно ниже чем к длительности сигнала на входе INTR.
RESET – сброс микропроцессора. Сигнал на этот вход подается при включении питания или при нажатии кнопки RESET. Обычно этот сигнал формируется генератором ГФ84. По этому сигналу происходит сброс в ноль всех флагов (то есть внешние прерывания запрещаются), в регистры ip, es, ds и ss загружаются нули, а в регистр cs – единицы. Так как МП всегда формирует адрес следующей команды по формуле A = (cs)×16 + (ip), то нетрудно видеть, что после сброса МП всегда стартует с адреса A = ffff0h + 0000h = ffff0h.
READY – вход готовности. При обращении к памяти или порту внешнего устройства МП всегда выполняет так называемый цикл шины. Этот цикл состоит из четырех тактов (Т1, Т2, Т3 и Т4). Вначале такта Т4 происходит обмен информацией между МП и ОП или ВУ. Однако если в системе стоит медленная память, она может к этому моменту оказаться не готовой к обмену. В этом случае внешние схемы должны сформировать нулевой сигнал на входе READY, означающий, что устройство к обмену не готово. В такте Т3 МП проверяет вход READY и, если на нем единица, переходит к такту Т4. В противном случае МП вводит между тактами Т3 и Т4 такты ожидания. В каждом такте ожидания МП опрашивает вход READY и так до тех пор, пока на READY не появится единица.
TEST – МП проверяет сигнал на входе TEST, только когда он выполняет команду wait. Если при этом на входе TEST стоит ноль, МП переходит к следующей команде. В противном случае МП вводит «холостые» такты и через каждые пять тактов снова опрашивает вход TEST. Обычно этот вход используется при стандартном подключении арифметического сопроцессора К1810ВМ87 (i8087).
MN/MX (minimum/maximum) – если на этот вход «запаяна» единица, МП работает в минимальном режиме, если ноль – в максимальном.
HOLD – захват. В минимальном режиме это вход. Если на этот вход приходит единица, МП прекращает выполнение текущей команды и отключается от шин. После этого МП находится в состоянии «спячки» до тех пор, пока на HOLD не появится ноль. Обычно сигнал на вход HOLD формирует контроллер прямого доступа к памяти.
HLDA (hold acknowledge) – подтверждение захвата. В минимальном режиме это выход. Этот сигнал обычно заводится на контроллер прямого доступа к памяти и сообщает последнему, что он может брать управление системной шиной на себя.
Рис. 4
A/D 15-0 (address/data) –16-ти разрядная мультиплексная шина адрес/данные. По этим линиям передается как адрес, так и данные, конечно в разные моменты времени. На эти линии МП выставляет 16 младших разрядов адреса при обращении к ОП, и весь адрес при обращении к порту ВУ. Адрес на эти линии выставляется в такте Т1 в сопровождении стробирующего сигнала на выходе ALE. В такте Т2 адрес снимается и далее по этим линиям происходит передача данных в сопровождении сигнала на выходе DEN. Поскольку адрес необходим нам до конца цикла шины (до такта Т4), его необходимо запоминать во внешнем регистре. Кроме того, для правильной работы системы шину адрес/данные демультиплексируют, то есть разделяют на шину адреса (ША) и шину данных (ШД), как показано на рис. 5. Здесь ШФ – шинные формирователи.
А16 – А19 – при обращении к ОП на эти линии МП выставляет старшие четыре разряда адреса. В такте Т2 адрес с этих линий снимается (то есть его также надо запоминать во внешнем регистре) и на эти линии МП выставляет сигналы состояния S3 – S6 (state). Последние обычно используются только при отладке системы.
BHE (bus high enable)– разрешение старшей половины шины данных. МП может производить обмен по ШД как словами (2 байта), так и отдельными байтами. В последнем случае байт может передаваться по старшей или по младшей половине ШД. Для решения этой проблемы и предназначен сигнал BHE. Если на BHE стоит ноль, то в данном цикле шины по старшей половине ШД будут передаваться данные. Совместно с сигналом на линии А0 сигнал BHE задает формат передачи информации по шине данных (смотри табл. 1).В такте Т2 сигнал BHE снимается и, следовательно, его надо запоминать во внешнем регистре. Далее на эту линию выставляется зарезервированный фирмой сигнал состояния S7.
RD (read)– чтение. Сигнал вырабатывается, когда МП выполняет операцию считывания информации из ОП или порта ВУ.
WR (write) – запись. Сигнал вырабатывается, когда МП выполняет операцию записи информации в ОП или порт ВУ.
Рис. 5
Таблица 1
M/IO (memory/input-output)– память/ВУ. Если МП обращается к ОП, на этот выход выставляется единица, если к ВУ – ноль. Данный сигнал позволяет разделить адресное пространство портов и адресное пространство памяти.
Сигналы RD, WR и M/IO подаются на внешние логические схемы, которые формируют системные управляющие сигналы MR («читаю память»), MW («пишу в память»), IOR («читаю порт») и IOW (« пишу в порт»).
DT/R (data transmit/receive –отправка/получение информации) – сигнал, дублирующий пару сигналов RD и WR. Если на выходе DT/R стоит единица, МП выдает информацию, если ноль – принимает. Сигнал используется для управления шинными формирователями, стоящими на ШД, задавая направление передачи информации, он более удобен для этой цели чем RD и WR, поскольку имеет большую длительность.
DEN (data enable – информация доступна) – сигнал, стробирующий передачу информации по ШД.
ALE (address latch enable – разрешено защелкнуть адрес)– сигнал, стробирующий выдачу адреса.
2.3 Назначение входов/выходов ВМ86 в максимальном режиме.
В максимальном режиме МП не вырабатывает сигналы WR, M/IO, DT/R, DEN, INTA и ALE. Вместо них МП вырабатывает соответственно сигналы LOCK, ST2, ST1, ST0, QS1 и QS0. Кроме того вход HOLD и выход HLDA становятся двунаправленными линиями, соответственно, RQ/GT0 и RQ/GT1.
LOCK – выход блокировки. Активный сигнал на этом выходе вырабатывается, если МП выполняет команду, перед которой программист поставил префикс lock. Этот префикс означает, что программист не хочет, что бы какое-либо событие прерывало выполнение данной команды. К таковым событиям относится, например, отключение МП от системной шины при прямом доступе к памяти или при захвате системной шины микропроцессором с более высоким приоритетом. В последнем случае сигнал с выхода LOCK должен быть заведен на внешние схемы арбитража, которые и обеспечивают удержание шины до конца блокированной команды. В минимальном режиме префикс lock блокирует восприятие запроса на входе HOLD.
S2, S1, S0 – сигналы состояния. Как уже говорилось выше, в максимальном режиме МП не вырабатывает ряд управляющих сигналов. В то же время эти сигналы необходимы системе для правильного функционирования. Поэтому в максимальном режиме в систему всегда вводится специальная микросхема системного контроллера К1810ВГ88 (i8288), которая и формирует недостающие сигналы. Сигналы на выходах S2-S0 характеризуют цикл шины, который в данный момент выполняет МП (смотри таблицу 2). Эти сигналы подаются на системный контроллер, и именно на основании этих сигналов последний формирует необходимые на данный момент системные управляющие сигналы.
Таблица 2.
S2
S1
S0
Цикл шины
Цикл подтверждения прерывания
1
Цикл чтения из порта ВУ
1
Цикл записи в порт ВУ
1
1
Цикл останова (процессор выполняет команду hlt)
1
Цикл выборки команды из ОП
1
1
Цикл чтения из ОП
1
1
Цикл записи в ОП
1
1
1
Нет цикла шины
RQ/GT0 и RQ/GT1 (request/grant-запрос/предоставление шины) – двунаправленные линии. Каждая из этих линий заменяет собой пару линий (HOLD, HLDA) минимального режима. Обычно используются при стандартном подключении арифметического сопроцессора и при организации прямого доступа к памяти. Если устройству, подключенному к линии RQ/GT, требуется системная шина, оно выставляет сигнал на эту линию, Получив этот сигнал МП прекращает выполнение текущей команды (если перед ней не стоит префикс lock), отключается от шин и подтверждает захват, выставляя сигнал на ту же линию RQ/GT. Когда устройство освобождает системную шину оно формирует еще один сигнал на этой же линии, подключая тем самым МП к системной шине. Отличие RQ/GT0 от RQ/GT1 заключается в том, что последняя линия имеет более низкий приоритет. То есть при одновременном приходе запросов на обеих линиях, будет обслужен запрос на линии RQ/GT0.
QS1, QS2 (queue state) – сигналы на этих линиях характеризуют состояние очереди команд МП. Эти две линии используются при стандартном подключении арифметического сопроцессора ВМ87, который анализирует состояние очереди, отслеживая момент начала выполнения «своей» команды.
2.4 Внутренняя архитектура МП ВМ86.
МП ВМ86 состоит из двух основных блоков:
• операционного устройства (ОУ);
• устройства шинного интерфейса (УШИ).
ОУ включает в себя восемь регистров общего назначения, регистр флагов, шестнадцатиразрядное АЛУ и микропрограммное УУ. Задачей ОУ является выполнение заданных в команде операций. УШИ содержит блок сегментных регистров, указатель команд (программный счетчик), сумматор адресов, очередь команд и буферы, обеспечивающие связь с шиной. УШИ обеспечивает обмен информацией между МП и ОП или портами ВУ. То есть УШИ выполняет циклы шины.
Оба этих устройства могут работать параллельно. Такая структура МП позволяет организовать, так называемый, конвейер команд. В процессе выполнения любой команды всегда имеется промежуток времени, когда системная шина оказывается свободна. Длительность этого промежутка зависит от сложности команды. Обычно, чем сложнее команда, тем длиннее данный промежуток. ШИ использует эти промежутки для опережающей выборки команд из памяти. То есть пока одна команда выполняется, другие команды считываются из памяти, поэтому к моменту начала выполнения команды она, как правило, уже находится внутри МП и не надо тратить время на ее выборку из ОП. Таким образом, конвейер команд позволяет повысить общее быстродействие системы. Отметим, что в МП ВМ86 реализован самый простой двухступенчатый конвейер. В современных МП число ступеней конвейера значительно больше (одна команда выполняется, другая выбирается из ОП, третья дешифрируется, для четвертой формируется адрес операнда и. т. д.).
Выбранные с опережением из ОП команды надо где-то внутри МП хранить. С этой целью в состав ШИ введена очередь команд, представляющая из себя стек, реализующий процедуру FIFO и имеющий глубину шесть байт. Машинные команды МП ВМ86 занимают от одного до шести байт (без учета префиксов). Таким образом, в очереди может одновременно находиться от одной до шести команд. Очередь хорошо заполняется, когда МП выполняет сложные команды (умножение, деление) и может оставаться наполовину пустой при выполнении последовательности простых команд.
Если процессор выполняет команду перехода (jmp, call и.т.д.), информация в очереди оказывается ненужной. Поэтому в этом случае МП автоматически очищает очередь команд и начинает заполнять ее заново.
2.5 Сегментация памяти.
Как уже отмечалось выше, МП 8086 имеет 20 адресных линий, то есть может адресовать ОП объемом 1 Мбайт. Эта память логическим образом разбивается на сегменты, объемом 64 Кбайт каждый, которые могут располагаться практически в любом месте памяти. Одновременно МП может работать с четырьмя такими сегментами. Они называются:
• сегмент кода, в нем располагается программа, которую выполняет МП;
• сегмент стека, в нем организуется стек;
• сегмент данных, в нем располагаются данные;
• дополнительный сегмент, обычно используется как дополнительный сегмент данных.
Каждому из этих сегментов ставится в соответствие находящийся внутри МП 16 разрядный сегментный регистр. Сегментный регистр cs соответствует сегменту кода, ss – стека, ds –данных и es – дополнительному сегменту.
Содержимое сегментного регистра задает начальный (базовый) адрес соответствующего сегмента в ОП. Однако сегментный регистр 16 разрядный, а адрес ОП должен быть 20 разрядным. Чтобы из шестнадцати разрядов получить двадцать, содержимое сегментного регистра при формировании адреса ОП сдвигают на 4 разряда влево (умножают на 16). Например, пусть cs=2231h, тогда начальный адрес сегмента кода равен 22310h. Отсюда можно сделать вывод, что начальный адрес любого сегмента всегда кратен шестнадцати. Это единственное ограничение на расположение сегментов в памяти. Других ограничений не существует, то есть сегменты могут быть полностью независимы друг от друга, а могут частично и даже полностью перекрываться.
При выполнении команды, если в ней требуется обращение к памяти, МП формирует по адресному коду, заданному в команде, так называемый эффективный адрес (Аэф).
Например, пусть
ds=2200h, bx=1000h, si=0770h
и выполняется команда
mov ax,[bx+si+2]
тогда
Аэф=(bx)+(si)+2=1000h+0770h+2=1772h
Сформированный Аэф рассматривается как внутрисегментное смещение, поэтому далее МП формирует физический адрес (Аф) по следующей формуле:
Аф = (сегментный регистр)×16 + Аэф.
Аф и является адресом ячейки ОП, к которой обращается МП. Для нашего примера (по умолчанию здесь в качестве сегментного регистра берется сегментный регистр ds):
Аф = (ds)×16 + Аэф = 22000h + 1772h = 23772h.
В процессе формирования Аэф возможно возникновение переноса из старшего разряда. При этом данный перенос попросту отбрасывается. Таким образом, после Аэф = ffffh идет Аэф = 0000h. Иначе говоря, достигнув конца сегмента мы автоматически переходим на его начало. Это так называемая кольцевая организация сегмента. Таким образом, существует только один способ выйти за пределы текущего сегмента – сменить содержимое соответствующего сегментного регистра.
В процессе формирования Аф также возможно возникновение переноса из старшего разряда. Как и в предыдущем случае, этот перенос попросту отбрасывается, Получается кольцевая организация памяти. Иначе говоря, никаким способом мы не можем сформировать адрес за пределами 1 Мбайта.
2.6 Программная модель МП ВМ86.
Программная модель ВМ86 представлена на рис. 6. Все регистры ВМ86 можно разбить на группы. Первую группу составляют РОНы, к которым относятся регистры ax, bx, cx и dx. Любой из этих регистров можно рассматриваться и как один шестнадцатиразрядный, и как пара восьмиразрядных регистров. Основное назначение РОНов – временное хранение информации, однако, на каждый из этих регистров в ВМ86 возлагается и ряд специальных функций.
Регистр ax – в нем формируется результат (или его часть) в командах умножения и деления. Кроме того, обмен информацией между МП и портами ВУ можно проводить только через регистры ax и al. То есть допустимы команды
out 20h,al и in ax,70h
и недопустимы
out 20h,ah и in bx,70h.
Регистр bx - первый базовый регистр процессора. Это единственный регистр из группы РОНов, который можно использовать для косвенной и базовой адресации. То есть допустимы команды
mov al,[bx] и add [bx +7],dx
и недопустимы
mov al,[ax] и add [bh +7],dx.
Если для адресации используется регистр bx, то, по умолчанию, в качестве сегментного регистра берется регистр ds.
Регистр cx используется в качестве счетчика в команде цикла loop и командах, перед которыми поставлен префикс повторения rep. То есть цикл или команда с префиксом будет повторяться до тех пор, пока сх не обнулится (естественно, после каждого прохода содержимое сх автоматически уменьшается). Кроме того, регистр cl используется в командах сдвига для задания числа сдвигов.
Регистр dx – это единственный регистр МП, который можно использовать для косвенной адресации портов ВУ. То есть, допустимы команды
out [dx],ax и in al,[dx].
Регистры bp, sp, si и di составляют группу регистров указателей. Основное их назначение – участвовать в формировании Аэф. Однако если для этой цели они не нужны, их можно использовать в качестве РОНов . Регистры этой группы могут быть только шестнадцатиразрядными.
Регистр bp - второй базовый регистр процессора. Если для адресации используется регистр bp, то, по умолчанию, в качестве сегментного берется регистр ss. Таким образом, использование для адресации регистра bp позволяет обращаться к области стека, как к обычной памяти.
Рис. 6
Регистры si и di – индексные регистры процессора. Используются для косвенной и базово-индексной адресации. При этом необходимо соблюдать следующее правило: в любой команде для адресации можно использовать только один базовый и только один индексный регистр. То есть, допустимы команды
sub [di],7 и mov cx,[bp + si +7]
и недопустимы
mov [bx+bp],al и mov dh,[si + di].
Регистр sp – указатель стека. Использовать его в качестве РОНа не рекомендуется.
Регистр ip не относится ни к какой группе и называется указателем команд. По своей сути – это программный счетчик. В нем всегда формируется смещение в кодовом сегменте и, таким образом, ip всегда задает адрес следующей команды программы. Сменить содержимое ip можно только командами перехода, то есть командами jmp, call, ret и др.
Регистры cs, ss, ds и es составляют группу сегментных регистров.
Регистр cs всегда используется вместе с регистром ip при формировании адреса следующей команды программы. Данный адрес формируется следующим образом:
Аф = (cs)×16 + (ip).
То есть содержимое cs задает начальный адрес сегмента кода.
Сегментный регистр ss задает начальный адрес сегмента стека и всегда используется вместе с регистром sp для формирования Аф при обращении к стеку:
Аф = (ss)×16 + (sp).
Содержимое сегментного регистра ds задает начальный адрес сегмента данных. В командах, оперирующих с данными, при формировании физического адреса ОП в качестве сегментного регистра по умолчанию (кроме случая, когда в качестве базового используется регистр bp) берется ds. Однако при этом мы всегда имеем возможность сменить сегмент, прямо указав сегментный регистр, который должен использоваться для формирования Аф, с помощью префикса замены сегмента. Например:
mov [bx],ax
Аф = (ds)×16 + (bx);
mov ss:[bx],ax
Аф = (ss)×16 + (bx).
Содержимое сегментного регистра es задает начальный адрес дополнительного сегмента. По умолчанию этот регистр используется только при формировании физического адреса приемника в строковых командах. В остальных случаях использование es задается с помощью префикса замены сегмента.
В таблице 3 показаны все возможные случаи формирования Аф и компоненты, принимающие участие в этом процессе
Регистр f – регистр флагов. Его формат приведен на рис. 7. В этом регистре определены следующие флаги:
cf (carry) – флаг переноса. Этот флаг устанавливается в единицу, если в процессе операции возникает перенос из старшего разряда (или был заем в старший разряд при вычитании). С этим флагом работают некоторые команды условных переходов. Программист может непосредственно влиять на значение этого флага, используя команды stc, clc и cmc (установить , сбросить, инвертировать).
pf (parity)– флаг четности. Устанавливается в единицу, если в младшем байте результата получилось четное число единиц. Флаг можно использовать для организации «контроля по четности», с ним работают некоторые команды условных переходов.
af (adjust) – флаг межтетрадного переноса. Устанавливается в единицу, если в процессе операции возникает перенос из 3-го бита в 4-й (или при заеме из 4-го бита при вычитании). С флагом работают команды коррекции для двоично-десятичной (BCD) арифметики.
zf (zero) – флаг нулевого результата. Устанавливается в единицу, если результат операции оказался равен нулю. С флагом работают некоторые команды условных переходов.
sf (sign)– флаг знака. Устанавливается в единицу, если в старшем разряде результата получилась единица, то есть результат является отрицательным числом. С флагом работают некоторые команды условных переходов.
Таблица 3
Вид операции
Сегментный регистр по умолчанию
Возможность смены сегментного регистра с помощью префикса
Внутрисегментное смещениие
Выборка команды
cs
нет
ip
Стековая операция
ss
нет
sp
Обращение к памяти (кроме bp в качестве базового регистра)
ds
cs, ss, es
Аэф
Обращение к памяти при bp в качестве базового регистра
ss
cs, ds, es
Аэф
Источник в строковой команде
ds
cs, ss, es
si
Приемник в строковой команде
es
нет
di
Обращение к ВУ
нет
нет
dx или прямая адресация
Рис. 7
of (overflow)– флаг переполнения. Устанавливается в единицу, если в результате выполнения арифметической операции произошло переполнение разрядной сетки. С флагом работает единственная команда into – «прерывание, если установлен флаг of».
tf (trap)– флаг трассировки. Если этот флаг установлен в единицу, программа выполняется в «пошаговом режиме», так как после каждой команды МП автоматически генерирует прерывание типа 1. Таким образом, этот флаг используется для отладки. У программиста нет в распоряжении команд, влияющих на этот флаг. Поэтому изменить значение флага tf можно только косвенным образом, через стек. Например, следующий фрагмент программы сбрасывает tf в ноль:
pushf
mov bp,sp
and [bp],0feffh
popf
if (interrupt enable)– флаг разрешения внешних прерываний. Если этот флаг установлен в ноль МП игнорирует запросы на прерывание, приходящие на вход INTR. Для работы с этим флагом есть две команды:
sti - if 1 – разрешить внешние прерывания;
cli - if 0 – запретить внешние прерывания.
df (direction)– флаг направления, задает автоинкремент или автодекремент регистров si и di в строковых командах. Программист имеет возможность влиять на этот флаг с помощью команд std и cld.
2.7 Организация оперативной памяти.
С точки зрения программиста оперативная память для ВМ86 представляет собой линейный массив ячеек форматом 1 байт каждая, с адресами от 00000h до fffffh (рис. 8).
Информация, располагаемая в ОП, может иметь следующие форматы:
• байт;
• слово (2 байта);
• двойное слово (4 байта).
При этом адресом слова или двойного слова считается адрес его младшего байта.
Физически память для МП86 организуется иначе. Память реализуется в виде 2-х банков: старшего и младшего. В младший банк входят все ячейки с четными адресами, в старший – все ячейки с нечетными адресами. Обращение к тому или иному банку (или к обоим сразу) определяется комбинацией сигналов на выходах BHE и A0 МП. Подключение банков к шине данных показано на рис. 9.
Банк подключается к ШД, когда на его вход CS приходит активный (нулевой) сигнал. При этом младший банк подключается к младшей половине ШД, а старший – к старшей половине ШД. Такая организация позволяет производить обмен между МП и ОП как по всей ШД, так и по отдельным ее половинам. Подобная архитектура приводит к следующему правилу: слова желательно располагать в памяти по четным адресам. Если слово располагается в ОП по четному адресу, то оно будет передаваться по ШД за один цикл шины, если же по нечетному – за два цикла шины. По той же причине двойные слова также желательно располагать по четным адресам.
Рис. 8.
2.8 Организация адресного пространства портов ВУ.
Существует два основных способа организации адресного пространства портов ВУ.
1) Раздельная организация адресных пространств ОП и портов ВУ. В этом случае к портам обращаются командами in и out, а к ОП – остальными командами. Соответственно МП выставляет единицу на выходе M/IO, если он обращается к ОП и ноль, если он обращается к порту. Таким образом сигнал на выходе M/IO позволяет различить ячейку памяти и порт, даже если они имеют одинаковые системные адреса.
В командах in и out можно использовать два типа адресации: прямую и косвенную. При прямой адресации адрес порта указывается в команде непосредственно (например, in al,60h) и имеет размер 1 байт. То есть таким способом мы можем задать 256 различных адресов портов. Учитывая, что МП вырабатывает сигналы RD и WR, мы можем считать, что при прямой адресации в системе можно использовать максимум 512 портов, половина из которых работает на ввод информации, а другая половина – на вывод.
При косвенной адресации адрес порта берется из регистра dx (например, out [dx],al). Поскольку данный регистр шестнадцатиразрядный, то, исходя из тех же соображений, в систему максимально можно поставить 128К портов, половина из которых работает на ввод, а другая половина – на вывод.
2) Отображение адресного пространства портов на адресное пространство памяти. При таком способе порты рассматриваются как ячейки ОП. Соответственно обращение к таким портам производится командами обращения к памяти, а не командами in и out. Сигнал на выходе M/IO при обращении к таким портам будет равен единице. Следовательно, такие порты и ячейки памяти не могут иметь одинаковые адреса. Такой способ позволяет наращивать число портов вплоть до 1М, правда за счет уменьшения объема ОП. В чистом виде на практике этот способ применения не находит, однако зачастую его используют в сочетании с первым способом.
Рис. 9
2.9 Методы обмена информацией между МП и портами ВУ.
Одна из основных проблем при обмене информацией между МП и ВУ заключается в том, что ВУ, как правило, работают значительно медленнее МП.
Прямой обмен. МП обращается к порту ВУ командой in или out и через определенный промежуток времени осуществляет обмен. Так как при этом он не выясняет, готово ВУ к обмену или нет, велика вероятность потери информации или неправильной ее передачи. Такой способ применяется при работе с ВУ, которые «всегда готовы к обмену». Например, так можно прочитать состояние переключателей конфигурации в IBM PC или вывести информацию на светодиоды. Инициатором обмена здесь является МП, он же и управляет обменом по СШ.
Обмен по опросу готовности. При этом способе ВУ подключается к ШД через два порта. Один из них предназначен для передачи данных, а другой порт хранит информацию, характеризующую текущее состояние ВУ. Один из битов этого порта показывает, готово ВУ к обмену или нет. Перед обменом МП читает порт состояния и анализирует бит готовности. Если выясняется, что ВУ к обмену не готово, МП снова читает порт состояния и снова анализирует готовность ВУ к обмену. И так до тех пор, пока ВУ не станет готово к обмену. Только после этого будет произведен обмен. Недостаток такого способа очевиден – МП, проверяя готовность ВУ к обмену, не выполняет никакой полезной работы. Поэтому этот способ применяется при обмене с быстродействующими ВУ, например ЦАП и АЦП. Инициатором обмена здесь является процессор, и обмен идет под его управлением.
Обмен по запросам на прерывание. ВУ, будучи готово к обмену, выставляет на МП запрос на прерывание. Получив этот запрос МП прерывает выполнение текущей программы, и переходит на подпрограмму обслуживания данного запроса, то есть производит обмен. Такой способ применяется для медленных ВУ, например для клавиатуры. Инициатором обмена здесь является ВУ, но сам обмен, как и ранее, идет под управлением МП.
Прямой доступ к памяти. Это специфический вид обмена, когда передача информации ведется между ОП и быстродействующим ВУ, минуя МП. Последний в обмене участия не принимает, более того, он отключен от СШ и как бы находится в «спячке». Поскольку обменом нужно управлять, в состав системы вводится контроллер прямого доступа к памяти (КПДП), который и вырабатывает необходимые управляющие сигналы и адреса ОП.
2.10 Параллельный программируемый адаптер К1810ВВ55 (i8255).
Эта микросхема наиболее часто используется для организации параллельных портов ввода-вывода в системах, построенных на базе МП фирмы Intel.
Схема подключения адаптера к СШ представлена на рис.10. Рассмотрим назначение входов/выходов адаптера.
CS (chip select – «выбор кристалла»). На этот вход через схему селектора (дешифратора) формируется активный (нулевой) сигнал, когда МП выставляет на ША адрес одного из внутренних регистров адаптера. Сложность схемы селектора сильно зависит от организации системы. В простых системах с малым числом портов селектор может вообще отсутствовать. Активный сигнал на CS подключает адаптер к ШД.
С точки зрения программиста внутри адаптера имеются четыре адресуемых устройства: порт A (PA), порт B (PB), порт С (РС) и регистр управляющего слова (РУС). К какому из четырех внутренних устройств обращается МП, когда на CS приходит активный сигнал, определяет информация на входах А1 и А0 (табл. 4).
D 7-0 – восьмиразрядная шина данных. По ней производится обмен информацией, в том числе и управляющей, между МП и внутренними устройствами адаптера.
Вход RD – «чтение». Задает вид операции. На этот вход заводится системный управляющий сигнал IOR.
Вход WR – «запись». На этот вход заводится системный управляющий сигнал IOW.
Таблица 4.
RESET – сброс. По этому сигналу все порты адаптера настраиваются на ввод в режиме 0. Как правило, этот вход на практике не используется.
РА – восьмиразрядный порт, который может быть настроен на ввод или на вывод в одном из трех режимов: режиме 0, режиме 1 или режиме 2.
РВ – восьмиразрядный порт, который может быть настроен на ввод или на вывод в одном из двух режимах: режиме 0 или режиме1.
РС – восьмиразрядный порт, который можно настроить на ввод или на вывод в режиме 0. В отличие от РА и РВ порт С разбит на две половины: старшую и младшую, каждую из которых можно независимо настроить на ввод или на вывод.
Режимы 1 и 2 на практике используются редко, поэтому мы здесь ограничимся рассмотрением режима 0.
Пусть, например, порт А настроен на ввод в режиме 0. Когда МП обращается к этому порту командой in al, port_A информация с внешних линий РА попадает на ШД. То есть в этом случае порт работает как коммутатор и передаваемая информация внутри адаптера не фиксируется.
Пусть РА настроен на вывод в режиме 0. По команде out port_A, al информация с ШД поступит в РА и там защелкнется. Естественно, что эта информация появится при этом и на внешних линиях РА.
Перед началом работы все порты адаптера должны быть настроены. Для этого достаточно передать в РУС настроечное слово, формат которого приведен на рис. 11.
Рис. 10
Рис. 11
Здесь D7 = 1. Эта единица и означает, что передается настроечное слово. При D7 = 0 передается специальная команда, которая здесь рассматриваться не будет.
D6, D5 – определяют режим работы РА:
00 – режим 0;
01 – режим 1;
10 – режим 2;
11 – тоже режим 2.
D4 = 1 – РА настраивается на ввод.
= 0 – РА настраивается на вывод.
D3 = 1 –старшая часть РС (линии РС 7-4) настраивается на ввод.
= 0 – старшая часть РС настраивается на вывод.
D2 = 1 – РВ настраивается на режим 1.
= 0 – РВ настраивается на режим 0.
D1 = 1 – РВ настраивается на ввод.
= 0 – РВ настраивается на вывод.
D0 = 1 – младшая часть РС (РС 3-0) настраивается на вывод.
= 0 – младшая часть РС настраивается на ввод.
В IBM PC/XT стоит микросхема ВВ55. При этом ее портам присвоены следующие системные адреса:
PA = 60h;
PB = 61h;
PC = 62h;
РУС = 63h.
При начальном старте XT выполняет две команды:
mov al, 99h
out 63h, al
то есть в РУС загружается двоичное число 10011001. Таким образом, все порты настраиваются на работу в режиме 0, РА и обе половины РС на ввод, а РВ на вывод. Начиная с IBM PC/AT, микросхема ВВ55 в системе отсутствует, но порты 60h и 61h существуют и выполняют те же функции.
2.11 Пример использования и программирования адаптера
Пусть в системе имеются принтер и фотосчитыватель. Подключение их к системной шине через порты адаптера ВВ55 показано на рис. 12.
Рис. 12
В соответствии с этой схемой произведем настройку портов адаптера (системные адреса внутренних устройств адаптера будем считать совпадающими с IBM PC/XT):
mov al,83h
out 63h,al
; все порты на режим 0, РА – на вывод, РВ – на ввод, старшая часть РС – на вывод, младшая – на ввод.
mov al,0
; обнуляем разряды РС 7-4.
out 62h,al
Пусть необходимо принять байт информации с фотосчитывателя. Обмен будем производить методом опроса готовности. Когда фотосчитыватель готов к выдаче очередного байта, он выставляет сигнал READY2. МП считывает этот байт через РВ и формирует (программным образом) положительный импульс на линии STB2, получив который фотосчитыватель снимает текущий байт и начинает готовить следующий.
m1: in al,62h
and al,8
jz m1
; проверка готовности фотосчитывателя
; к выдаче очередного байта.
; читаем РС
; бит 3 равен единице ?
; если нет – переход на m1
in al,61h
mov [200h],al
; читаем байт с фотосчитывателя и
; заносим в память, например, по
; адресу ds:200h
; читаем РВ и заносим считанный байт
; в ОП
mov al, 10h
out 62h,al
mov al,0
out 62h,al
; формируем импульс на линии PC4
; выставляем единицу на РС4
; выставляем ноль на РС4
Аналогично осуществляется вывод байта информации на принтер:
m2: in al,62h
and al,4
jz m2
; проверяем READY1
mov al,ah
out 60h,al
; выводим на принтер байт информации
; например, из регистра ah
mov al, 40h
out 62h,al
mov al,0
out 62h,al
; формируем STB1
2.12 Программируемый таймер К1810ВИ54 (i8254).
Данная микросхема широко применяется в системах на основе МП фирмы Intel для организации временных задержек, организации службы системного времени и. т. д.
Таймер содержит три независимых канала, соответственно канал 0, канал 1 и канал 2. Внутри каждого канала стоит шестнадцатиразрядный счетчик, работающий на вычитание. Счетчик можно программным образом настроить на счет в двоичной или двоично-десятичной системе счисления. Любой канал таймера можно запрограммировать на работу в одном из шести режимов, соответственно режим 0, режим 1,…., режим 5.
При программировании канала в его регистр управляющего слова (РУС) передается настроечное слово (байт). Хотя у каждого канала свой РУС, все они имеют один системный адрес и поэтому, с точки зрения программиста, внутри таймера один РУС. Таймер определяет, какому каналу предназначено настроечное слово по внутреннему содержимому этого слова.
Схема подключения таймера к СШ приведена на рис. 13.
Информация на линиях А1 и А0 задает одно из четырех адресуемых устройства внутри таймера:
А1=0, А0=0 – канал 0;
А1=0, А0=1 – канал 1;
А1=1, А0=0 – канал 2;
А1=1, А0=1 – РУС.
CLK - вход синхроимпульсов. На этот вход поступают импульсы, которые считает канал. Декремент счетчика происходит по заднему фронту импульсов на входе CLK.
Рис. 13
GATE – управляющий вход. Если на этом входе единица, счетчик канала считает импульсы, приходящие на CLK, если ноль – не считает. В некоторых режимах снятие и подача единицы на входе GATE инициирует перезапуск счетчика.
OUT – выход канала. Вид сигнала на этом выходе зависит от режима, на который настроен канал.
Остальные входы/выходы таймера аналогичны одноименным входам/выходам адаптера ВВ55 (см. раздел 2.10).
Формат настроечного слова канала приведен на рис. 14.
Рис. 14
Разряды D7, D6 задают номер канала, в который передается настроечное слово:
D7=0, D6=0 – канал 0;
D7=0, D6=1 – канал 1;
D7=1, D6=0 – канал 2;
D7=1, D6=1 – специальная команда (на практике используется редко).
Как видно из рис. 14, таймер связан с СШ восьмиразрядной шиной данных. В то же время формат счетчика канала – два байта. Поэтому имеются различные варианты загрузки счетчика и чтения его содержимого. Эти варианты задают разряды D5 и D4 настроечного слова:
D5=0, D4=0 – специальный режим «чтение на лету»;
D5=0, D4=1 – передается только старший байт;
D5=1, D4=0 – передается только младший байт;
D5=1, D4=1 – передаются оба байта (за две передачи, сначала младший, а потом старший.
Прочитать содержимое счетчика канала можно двумя способами. Первый способ требует остановки счета, для чего надо либо прекратить подачу импульсов на вход CLK, либо снять единицу со входа GATE. Второй способ не требует остановки счета и называется «чтение на лету». В этом случае в настроенный, работающий канал надо передать еще одно настроечное слово (его формат смотри на рис. 15).
Рис. 15
Здесь, как и ранее, D7 и D6 задают номер канала, а звездочки означают безразличное значение. Получив такой приказ, канал автоматически фиксирует текущее значение счетчика в буфере, откуда его затем можно считать за одну или две передачи.
Разряды D3 – D1 (рис. 14) задают режим, в котором будет работать канал (соответственно 000 – режим 0,…, 101 – режим 5).
Разряд D0 задает систему счисления, в которой будет работать канал. При D0=0 задается двоичная, а при D0=1 – десятичная система счисления.
Далее перечислим названия режимов и их смысл.
Режим 0 - программируемая задержка
После загрузки управляющего слова в регистр режима канала на выходе ОUT устанавливается напряжение низкого уровня; загрузка счетчика не изменяет это состояние. Затем, если GATE =1, начинается декремент счетчика (последовательное вычитание из него единицы). В момент, когда счетчик обнулится, на выходе OUT устанавливается напряжение высокого уровня. Высокий уровень напряжения на выходе OUT сохраняется до загрузки счетчика новым значением. Счет разрещен только при наличии сигнала высокого уровня на входе GATE. Низкий уровень этого сигнала или ниспадающий фронт запрещают счет. Счет будет продолжен при условии восстановления уровня логической 1 на входе GATE. Перезагрузка счетчика в процессе счета приводит к следующему: загрузка младшего байта останавливает текущий счет, загрузка старшего байта запускает новый цикл счета. Минимально допустимое значение счетчика равно 2.
Режим 1 - программируемый одновибратор
В этом режиме на выходе счетчика формируется отрицательный импульс длительностью t = N×T, где N - число, загруженное в счетчик, T - период тактовых импульсов. Низкий уровень (логический 0) на выходе OUT устанавливается со следующего такта после подачи на вход GATE сигнала высокого уровня ("счет разрешен"). Загрузка в счетчик нового числа не влияет на длительность текущего импульса, а учитывается при следующем запуске. Перезапуск счетчика производится нарастающим фронтом входа GATE (без перезагрузки счетчика). Минимальное допустимое значение N равно 1.
Режим 2 - программируемый делитель (генератор) частоты
В этом режиме счетчик таймера работает как делитель частоты F на N, где N число, загружаемое в счетчик. При этом из сигнала, поступающего на вход CLK микросхемы, на ее выходе OUT формируется сигнал с частотой F/N. Длительность уровня логической 1 для формируемого сигнала равна (N-1)*T, а длительность уровня логического 0 равна T, где Т - один период синхронизации счетчика по входу CLK. Другими словами, каждый раз при достижении счетчиком единицы, на выходе OUT появляется отрицательный импульс длительностью один такт. Если в процессе работы счетчика осуществить его перезагрузку, то текущий период не изменяется , а следующий будет соответствовать новому значению N. Вход GATE используется для аппаратной синхронизации. Так, по сигналу по сигналу GATE, равному 0, на выходе OUT устанавливается сигнал 1, а с переходом сигнала GATE к значению 1 счет возобновляется с начального значения N.
Режим 3 - программируемый генератор меандра
В этом режиме программируемый интервальный таймер выполняет функции программируемого генератора частоты со скважностью 2. Период выходного сигнала t = N×T, при этом длительность положительного и отрицательного полупериодов равна T×N/2, если N - четное число. При нечетном N положительный период (на выходе OUT установлен сигнал логической 1 ) равен T×(N+1)/2, а отрицательный (на выходе OUT установлен сигнал логического 0) - T×(N-1)/2. Перезагрузка счетчика в процессе счета новой величиной не оказывает влияния на текущий период. Изменен будет следующий период выходного сигнала. Низкий уровень сигнала на входе GATE запрещает счет, на выходе OUT устанавливается сигнал высокого уровня. Высокий уровень GATE разрешает счет, а нарастание его запускает счетчик с начального состояния N. Генератор меандра не работает при загрузке в счетчик числа N=3.
Режим 4 - генератор одиночного импульса (счетчик событий)
В этом режиме работы по окончании отсчета числа N, загруженного в счетчик, на выходе OUT формируется сигнал 0 с длительностью, равной периоду T, а затем сигнал вновь переходит в исходное состояние OUT = 1. Для повтора цикла необходима перезагрузка счетчика. Перезагрузка счетчика возможна только программным способом. Как и ранее, под программной перезагрузкой здесь понимается загрузка нового значения константы пересчета N в счетчик с шины данных. При этом загрузка младшего байта не оказывает влияния на текущий счет, а загрузка старшего байта запускает новый цикл счета. Вход GATE имеет то же назначение , что и в режиме 0 : при GATE = 0 счет запрещен, при GATE = 1 счет разрешен. Таким образом, указанный режим может быть использован для формирования одиночного импульса, вырабатываемого через определенную задержку после перезагрузки счетчика. Минимальное допустимое значение числа N равно 1.
. Режим 5 - генератор одиночного импульса (счетчик событий) с аппаратным перезапуском
Работа таймера в режиме 5 по выходному сигналу аналогична работе в режиме 4, а по действию сигнала GATE - режиму 1, в котором, как у одновибратора, запуск счета выполняется передним фронтом сигнала GATE. Если счет не завершен до конца, то по переднему фронту сигнала GATE счет начинается с начала. Таким образом, счетчик является перезапускаемым. Возможна перезагрузка счетчика новой величиной N во время счета, что не влияет на длительность текущего цикла, а новая загруженная величина N будет обработана в следующем цикле счета.
В любой IBM – подобной ПЭВМ стоит микросхема таймера ВИ53. При этом внутренним устройствам таймера присвоены следующие системные адреса:
• канал 0 – 40h
• канал 1 – 41h
• канал 2 – 42h
• РУС - 43h.
Канал 0 отведен для службы системного времени. На выходе этого канала формируются импульсы с частотой примерно равной 18,2 Гц. Эти импульсы подаются на вход IR0 контроллера прерываний ВН59 и представляют собой запросы на прерывание от таймера.
Канал 1 используется для регенерации динамической памяти. Сигнал с выхода этого канала подается на вход DREQ0 контроллера прямого доступа к памяти ВТ37 и является запросом на прямой доступ к памяти.
Канал 2 предназначен для выработки звуковых сигналов. Его выход заведен на встроенный динамик. Выдачей выходного сигнала канала 2 на динамик управляют биты 1 и 0 порта 61h.
Схема использования таймера в IBM – подобных ПЭВМ приведена на рис. 16.
Как видно из схемы, биты 1 и 0 порта 61h управляют выдачей частоты на динамик. Для настройки канала 2 надо выполнить две команды:
mov al,0b6h
out 43h,al
; канал 2 настраивается на предачу
; обеих байтов, на режим 3,
; на двоичный счет
Запретить и разрешить звучание можно командами:
in al,61h
and al,0fch
out al,61h
; запретить звучание
in al,61h
or al,3
out 61h,al
; разрешить звучание
Рис. 16
2.13 Пример использования таймера.
Пусть, например, при наличии в системе fопорной = 1 МГц нам надо получить fвыходную = 1 Гц. То есть нам надо разделить fопорную на 106. Поскольку один канал такой коэффициент пересчета обеспечить не может, придется использовать два канала, например, каналы 0 и 1. Схема их соединения приведена на рис. 17.
Оба канала настраиваются на работу в режиме 3, на десятичный счет и в каждый из них загружается коэффициент пересчета, равный 103. Произведение этих двух коэффициентов и дает в результате 106. Далее приводится программа настройки и загрузки каналов. При этом считаем, что каналы и РУС имеют системные адреса, соответствующие IBM ПЭВМ.
mov al,37h
out 43h,al
; настраиваем канал 0
mov al,77h
out 43h,al
; настраиваем канал 1
mov al,0
out 40h,al
mov al,10h
out 40h,al
; загружаем (за две передачи)
;коэффициент пересчета в канал 0
mov al,0
out 41h,al
mov al,10h
out 41h,al
; загружаем (за две передачи)
;коэффициент пересчета в канал 1
Рис. 17
2.14 Обработка прерываний.
Под прерыванием понимается некоторое событие, заставляющее МП прервать выполнение текущей программы и перейти к подпрограмме обработки (обработчику) этого события. После того, как обработчик завершает свою работу, МП возвращается к прерванной программе, в ту точку, где она была прервана.
Все прерывания в системе можно разделить на внутренние и внешние. Внешние прерывания вызываются событиями, внешними по отношению к МП, а внутренние – событиями, происходящими внутри МП.
Конечно, обработка прерываний в МП различных типов имеет свои особенности, однако общая схема действий для любых МП остается одной и той же.
При обработке внутреннего прерывания МП «известна» его причина, а следовательно известен источник запроса. Поэтому, укрупнено, при внутреннем прерывании МП выполняет следующие действия:
• запоминает в стеке адрес возврата в прерываемую программу;
• определяет начальный адрес обработчика для известного источника запроса и передает управление этому обработчику;
• когда обработчик завершает свою работу, достает из стека адрес возврата, возвращая тем самым управление прерванной программе.
Внешние прерывания отличаются от внутренних тем, что МП неизвестен источник запроса. Следовательно, для внешнего прерывания в приведенную выше схему действий добавляется еще один этап: прежде чем определить начальный адрес обработчика, МП должен определить источник запроса.
Существуют два метода определения внешнего источника запроса:
• метод опроса;
• векторные прерывания.
Метод опроса. Этот метод можно реализовать, например, следующим образом. В систему вводится специальный порт (или несколько портов, при большом числе внешних источников прерываний). Все внешние запросы заводятся на входы этого порта, причем для каждого запроса отводится один бит порта. Одновременно, все запросы через схему ИЛИ заводятся на вход INTR МП. на рис. 18 приводится подобная схема для восьми внешних источников прерываний (IR7 – IR0).
Восприняв запрос на входе INTR, МП выполняет следующий фрагмент программы:
in al, port_int ; читаем port_int
shl al, 1 ; сдвигаем содержимое al на один разряд влево
jc obr7 ; если флаг cf установлен, то это запрос по ли
; нии IR7, и мы переходим к бработчику этого
; прерывания
shl al, 1 ; сдвигаем al еще на один разряд влево
jc obr6 ; если cf установлен, это запрос по IR6
и. т. д.
Рис. 18.
Возможна ситуация, когда МП получает сразу несколько запросов на прерывание от разных внешних источников. Чтобы МП мог в такой ситуации функционировать, всем источникам запросов присваиваются приоритеты. При одновременном поступлении нескольких запросов, обслужен будет запрос с наивысшим приоритетом. Для нашего примера старший приоритет будет у IR7, а младший – у IR0. Для того чтобы изменить приоритеты в нашем примере на противоположные, достаточно использовать команду сдвига вправо.
Достоинством метода опроса являются небольшие аппаратурные затраты, а недостатком – медленная реакция МП на запросы с низким приоритетом.
Векторные прерывания. Под вектором прерывания обычно понимают начальный адрес обработчика данного прерывания. При данном методе в систему вводится специальная схема, называемая контроллером прерываний. Когда МП выставляет сигнал подтверждения прерывания, контроллер прерываний выдает МП вектор данного прерывания или информацию, позволяющую определить этот вектор. Более подробно векторные прерывания будут рассмотрены ниже при рассмотрении контроллера прерываний.
2.15 Система прерываний ВМ86.
В МП ВМ86 каждому источнику запроса на прерывание ставится в соответствие так называемый тип (номер) прерывания. Тип имеет формат 1 байт. То есть всего возможно 256 различных источников запросов. Для того чтобы МП по известному типу мог определить начальный адрес обработчика, в ОП создается таблица векторов прерываний. Каждый вектор представляет собой пару «сегмент:смещение» и однозначно задает начальный адрес обработчика прерывания данного типа. В ОП вектор занимает 4 байта. Таблица прерываний ВМ86 всегда располагается в младшем Кбайте ОП. Ее формат приведен на рис. 19.
Здесь displ и disph – соответственно младший и старший байт смещения, а segl и segh – младший и старший байт сегмента. Из рис.20 видно, что для определения адреса вектора достаточно взять тип и умножить его на 4. Именно так и вычисляет адрес вектора МП.
При восприятии любого прерывания ВМ86 выполняет следующую последовательность действий:
• запоминает в стеке содержимое регистра флагов f и адрес возврата (содержимое регистров cs и ip);
• по известному типу находит в таблице соответствующий вектор и загружает disp в ip, а seg – в cs, тем самым, передавая управление обработчику.
Рис. 19
Этот процесс можно формально описать следующим образом:
sp (sp)-2
Аф = (ss)×16 + (sp)
Аф (f)
sp (sp)-2
Аф = (ss)×16 + (sp)
Аф (cs)
sp (sp)-2
Аф = (ss)×16 + (sp)
Аф (ip)
Аф = тип × 4
ip (Аф)
Аф = тип × 4 + 2
cs (Аф)
Так как таблица прерываний располагается по младшим адресам ОП, никакие сегментные регистры в формировании адреса вектора участия не принимают.
Помимо рассмотренных выше двух пунктов, МП также сбрасывает в ноль флаги if и tf, маскируя внешние прерывания и запрещая пошаговое выполнение обработчика.
Источники запросов для ВМ86 показаны в таблице 5.
Таблица 5
Источник запроса (вид прерывания)
Тип
Приоритет
Прерывание по ошибке деления
1
Прерывание по флагу tf
1
4
Прерывание по входу NMI
2
2
Прерывание по команде int3
3
1
Прерывание по команде into
4
1
Программные прерывания (по команде int n, где n = 0 – 255)
0 - 255
1
Прерывания по входу INTR
0 - 255
3
Здесь 1 – старший приоритет, 4 – младший.
Далее рассмотрим кратко имеющиеся виды прерываний.
Прерывание по ошибке деления (divided overflow). Это прерывание возникает при выполнении команд деления div и idiv, если формат результата (частного) превышает формат регистра-приемника. То есть, с точки зрения МП, результат деления равен бесконечности. В частности такая ситуация возникает при попытке деления на ноль.
Прерывание по флагу tf. Это прерывание возникает после выполнения любой очередной команды программы, если флаг tf установлен в единицу. При переходе к обработчику МП сбрасывает tf в ноль, поэтому обработчик выполняется не в пошаговом, а в автоматическом режиме. При возврате из обработчика по команде iret МП восстанавливает (выталкивает из стека) старое содержимое регистра флагов f. Флаг tf при этом снова устанавливается в единицу и МП возвращается в пошаговый режим. Обработчик этого прерывания обычно выводит на экран содержимое внутренних регистров МП.
Прерывание по команде int3. Это однобайтовая команда «прерывание в контрольной точке». Используется при отладке программы. Располагаются эти команды в критических местах программы (например, их туда может вставлять debugger). Обработчик этого прерывания также обычно выводит на экран содержимое регистров МП.
Прерывание по команде into. Команда проверяет состояние флага переполнения of, и если он установлен в единицу происходит прерывание.
Прерывание по команде int n. Это двухбайтная команда, в которой n задает тип прерывания и может принимать значение от 0 до 255. Таким образом с помощью такой команды мы можем вызвать любой обработчик. Собственно говоря, команда int n представляет из себя команду межсегментного вызова подпрограммы и в этом смысле подобна команде call far. Разница между этими командами в том, что int n занимает в памяти два байта, а call far – пять, int n сохраняет в стеке содержимое регистра флагов f, а call far не сохраняет. Команды int n используются для обращения к системным библиотечным подпрограммам (например, к средствам DOS и BIOS).
Прерывания по входам INTR и NMI были рассмотрены ранее.
2.16 Контроллер прерываний К1810ВН59 (i8259).
Данная микросхема предназначена для обслуживания двух различных групп МП. К первой группе относятся МП 580 и 8085, ко второй – 8086, 8088, 80286, 80386 и. т. д. Мы рассмотрим работу ВН59 при обслуживании МП второй группы. Подключение ВН59 к системной шине показано на рис. 20.
Рис. 20
Контроллер имеет восемь входов запросов на прерывание (IR7 – IR0). Восприняв запрос на одном из этих входов ВН59, формирует сигнал на выходе INT. Этот сигнал подается на вход INTR ВМ86. Если внешние прерывания не замаскированы, МП подтверждает прерывание, выставляя два сигнала на выходе INTA. Эти сигналы поступают на одноименный вход контроллера, и по второму из них ВН59 выставляет на ШД тип прерывания. Этот тип он формирует следующим образом: старшие пять разрядов типа задает программист при настройке контроллера, а на место младших трех разрядов ВН59 подставляет двоичный номер линии, по которой пришел запрос.
Несмотря на то, что внутренняя архитектура ВН59 включает в себя довольно много различных регистров, с точки зрения программиста, контроллер содержит всего два адресуемых устройства, выбор между которыми определяет сигнал на линии А0.
В системе могут использоваться несколько ВН59, соединенных каскадно. При этом один контроллер является ведущим, а все остальные ведомыми. Выходы INT ведомых контроллеров заводятся на входы IRi ведущего контроллера. Таким образом, максимальное число контроллеров в системе равно девяти, а максимально возможное число источников внешних прерываний равно 64. На рис. 21 показан пример каскадного соединения контроллеров.
Перед началом работы все контроллеры должны быть настроены. Для этого на каждый ВН59 надо подать три или четыре команды инициализации (ICW1 – ICW4). Три команды подаются, если в системе один контроллер прерываний, четыре – если несколько. Далее рассмотрим упрощенные форматы этих команд для второй группы процессоров.
ICW1 передается при А0=0 и имеет формат, приведенный на рис. 22.
Если D1=0 – в системе несколько контроллеров и, следовательно, будет команда инициализации ICW3. При D1=1 – в системе один контроллер и ICW3 передаваться не будет.
ICW2 передается при А0=1 и имеет формат, приведенный на рис.23. Здесь Т7-Т3 – старшие пять разрядов типа прерывания.
Формат ICW3 различается для ведущего и ведомых контроллеров. Для ведущего: если в i-ом разряде ICW3 стоит единица, значит к линии IRi подключен ведущий контроллер. Для ведомого ICW3 имеет формат, приведенный на рис 24. Передается ICW3 при А0 = 1.
ICW4 передается при А0=1 и обычно имеет формат, приведенный на рис. 25.
Рис. 21
Рис. 22
Рис. 23
N2
N1
N0
• Здесь N 2-0 – двоичный номер линии IR ведущего контроллера, к которой подключен данный ведомый.
Рис. 24
Рис. 25
В IBM PC/XT стоит один контроллер ВН59. Ему назначены системные адреса 20h (А0=0) и 21h (А0=1). Настройка ВН59 в XT производится следующей последовательностью команд:
mov al, 13h ; передаем ICW1, ICW3 не будет
out 20h, al
mov al, 8 ; передаем ICW2. Старшие разряды типа задаем
out 21h, al ; равными 00001. Таким образом, для линии IR0
; (прерывание от канала 0 таймера) контроллер
; будет вырабатывать тип = 08h, для линии IR1
; (прерывание от клавиатуры) – тип = 09h, и. т. д.
mov al,1 ; передаем ICW4
out 21h, al
Начиная с PC/AT, в системе стоит два ВН59. При этом все вышесказанное для ВН59 в ХТ является справедливым для ведущего в АТ.
После того как ВН59 настроен, все остальные настроечные слова он воспринимает как команды управления. Всего имеется три таких команды. Обычно их обозначают OCW1, OCW2 и OCW3.
OCW1 передается при А0 = 1. Если в i-ом разряде OCW1 стоит единица, вход IRi контроллера маскируется и запросы на этом входе ВН59 восприниматься не будут до тех пор, пока программист его не размаскирует.
Во избежание конфликтов всем входам IR контроллера присваиваются приоритет. Если программист не задает приоритеты линий IR, по умолчанию линии IR0 присваивается старший, а линии IR7 – младший приоритет. Команда OCW2 (передается при А0 = 0) позволяет менять приоритеты линий IR.
Пользователь должен знать о следующей важной особенности работы контроллера ВН59. Если контроллер настроен на «обычный конец прерывания», то восприняв запрос на линии IRi он автоматически маскирует эту линию и все линии IR с более низкими приоритетами. Иногда говорят что контроллер «ставит штору». Снимать штору самостоятельно контроллер не умеет. Это должен делать программист передав в контроллер команду управления OCW2 формата: 20h. Как правило штора снимается в конце обработчика. Например в конце обработчика прерывания от клавиатуры должны стоять две команды:
mov al,20h
out 20h,al
; снимаем штору в ХТ или у ведущего
; в АТ
Если эти команды не поставить, клавиатура будет заблокирована.
OCW3 передается при А0 = 0 и на практике используется редко.
ВН59 не предназначен для использования в многопроцессорных системах, поскольку «не умеет» распределять прерывания между имеющимися в системе процессорами. Поэтому (начиная с Pentium) в тех моделях процессоров, которые поддерживают многопроцессорные конфигурации, используется контроллер прерываний APIC (advanced programmable interrupt controller). При этом сам МП имеет встроенный APIC (local APIC) и, кроме того, в системе имеется общий внешний APIC (I/O APIC). Последний воспринимает прерывания от ВУ и, в зависимости от настройки, распределяет их обработку между процессорами (между встроенными APIC). Общение между внешним и встроенным APIC осуществляется либо по СШ (Pentium 4), либо по специальной шине APIC (более ранние процессоры). Если МП стоит в однопроцессорной сиистеме, внутренний APIC может быть настроен на работу с ВН59. Настройка внутреннего APIC в защищенном режиме производится только на нулевом уровне привилегий.
2.17 Дополнительная информация о настройке ВН59.
Хотя с практической точки зрения приведенной в предыдущем разделе информации о ВН59 вполне достаточно для успешной работы с этой микросхемой, в этом разделе без комментариев приводятся полные сведения о настройке контроллера.
• Формат ICW1
• Формат ICW 2 (имеется два варианта этой команды)
А0=1
А15
А14
А13
А12
А11
А10
А9
А8
Это вариант для МП 580. Команда задает старший байт адреса для команды
call addr16, которую формирует ВН59 для МП 580.
А0=1
Т7
Т6
Т5
Т4
Т3
*
*
*
Это вариант для ВМ86 и старше. В команде задаются пять старших разряда типа прерывания для линии IR0. Значение трех младших разрядов команды безразличны. Вместо этих разрядов ВН59 автоматически подставляет номер линии, по которой он принял запрос. Например, если пришел запрос на линию IR2, ВН59 сформирует следующий тип прерывания: Т7 Т6 Т5 Т4 Т3 0 1 0.
• Формат ICW3 (имеется два варианта этой команды).
А0=1
I 7
I 6
I 5
I 4
I 3
I 2
I 1
I 0
Это вариант для ведущего КП. Если в разряде Ii стоит единица, к входу IRi подключен ведомый КП. Например, ICW3 = 00101100 - в системе три ведомых КП, подключенных к входам IR5, IR3 и IR2 ведущего КП.
А0=1
*
*
*
*
*
N2
N1
N0
Это вариант для ведомого КП. Три младших бита команды задают ведомому номер линии ведущего, к которой данный ведомый подключен. Остальные биты команды не имеют смысла. Например, ICW3 = 00000101 – ведомому сообщают, что он подключен к IR5 ведущего.
• Формат ICW4
• Формат OCW1
А0=1
M7
M6
M5
M4
M3
M2
M1
M0
Единица в i-ом разряде OCW1 маскирует линию IRi. Напрмер, OCW1 = 00011001 – маскируются линии IR4, IR3 и IR0. Для того чтобы размаскировать все линии надо подать OCW1 = 00000000.
• Формат OCW2
Здесь Ц – циклический сдвиг приоритетов, СКП – специальный конец прерывания, КП – конец прерывания (снятие шторы), N2, N1, N0 – номер линии IRi.
• №1 – обычный конец прерывания (сброс шторы);
• №2 – специальный конец прерывания ( сброс шторы с i-й линии);
• №3 – циклический сдвиг уровней приоритета с обычным концом прерывания, установка дна приоритетного кольца по обслуженному запросу;
• №4 – циклический сдвиг уровней приоритета со специальным концом прерывания;
• №5 – разрешение вращения уровней приоритетов;
• №6 – сброс разрешения вращения уровней приоритетов;
• №7 – циклический сдвиг уровней приоритетов без окончания прерывания, N2-0 – двоичный кол дна приоритетного кольца.
• Формат OCW3 (A0 = 0) здесь не приводится.
2.18 Прямой доступ к памяти.
Обычно передача байта, например, из ВУ в ОП производится по следующей схеме. За один цикл шины информация считывается из порта ВУ и запоминается во внутреннем регистре процессора, затем, также за один цикл шины, эта информация передается из процессора в ОП. Таким образом, данная схема требует двух циклов шины на передачу одного байта. Однако скорость обмена можно увеличить, если передавать байт из порта ВУ в ОП напрямую, минуя процессор. Обмен при этом требует только одного цикла шины. Такой режим обмена называется прямым доступом к памяти (ПДП).
На время ПДП процессор отключается от системной шины, поэтому в систему вводится специальная схема контроллера ПДП (КПДП), которая и управляет обменом.
Пусть, например, надо передать байт информации из ОП в порт ВУ. Предварительно КПДП должен быть задан адрес ячейки ОП, откуда будет передаваться информация и направление передачи. Когда ВУ потребуется прочитать данный байт, оно формирует запрос на ПДП, поступающий на контроллер. Последний формирует активный сигнал на вход HOLD МП. Получив этот сигнал МП, прекращает выполнение программы, отключается от шин и вырабатывает сигнал подтверждения захвата HLDA. С этого момента управление системной шиной берет на себя КПДП. Для нашего примера КПДП выполняет следующие действия: вырабатывает сигнал подтверждения ПДП, подключающий порт ВУ к ШД, выставляет на ША адрес ячейки ОП, вырабатывает сигналы MR и IOW, задающие вид операции соответственно для ОП и ВУ. После передачи байта КПДП снимает активный сигнал с входа HOLD МП, возвращая последнему управление системной шиной.
Передача байта из ВУ в ОП производится аналогично, меняются только сигналы, задающие вид операции для ОП и ВУ.
При ПДП возможна передача целого блока информации. В этом случае КПДП предварительно задается направление передачи, начальный адрес блока в ОП и размер блока. После передачи очередного байта сигнал HOLD не снимается, содержимое счетчика байт уменьшается на единицу, а адрес ячейки ОП либо уменьшается, либо увеличивается (в зависимости от настройки КПДП) на единицу. Процесс обмена продолжается, пока счетчик байт не обнуляется.
2.19 Контроллер прямого доступа к памяти К1810ВТ37 (i8237).
Данная микросхема включает в себя четыре независимых канала ПДП: соответственно канал 0, канал1, канал 2 и канал 3. Каждый канал может находится в двух основных режимах: режиме программирования и режиме ПДП. В процессе программирования канал может быть настроен на работу в следующих режимах:
1. Режим одиночной передачи. В этом режиме канал осуществляет передачу байта информации между ОП и портом ВУ, после чего КПДП возвращает шину МП. В этом режиме можно задавать блок информации, но передаваться он будет побайтно.
2. Режим блоковой передачи. В этом режиме канал производит передачу блока информации. КПДП не возвращает шину МП до тех пор, пока не будет передан весь блок.
3. Режим передачи по требованию. По смыслу это та же блоковая передача, однако, после передачи каждого байта КПДП проверяет вход запроса на ПДП (DREQ) канала. Если на нем стоит активный сигнал, значит ВУ готово к дальнейшему обмену и передача продолжается. Если на DREQ стоит пассивный сигнал, значит ВУ к дальнейшему обмену не готово, передача прекращается (до нового запроса от этого ВУ) и шина возвращается МП.
4. Каскадный режим. В системе может стоять несколько КПДП, но при этом они соединяются каскадно (один ведущий, остальные ведомые). Сигнал с выхода HRQ ведомого заводится не на вход HOLD МП, а на вход DREQ одного из каналов ведущего. Если какой-либо канал КПДП настроен на каскадный режим, значит к входу DREQ этого канала подключен ведомый контроллер.
Существует специфический вид передачи, который называется «память – память». Как следует из названия, обмен здесь идет не между ОП и ВУ, а между двумя областями ОП. Для такой передачи используются два фиксированных канала: канал 0 и канал 1. В канале 0 задается начальный адрес области ОП, откуда будет передаваться информация. В канале 1 – начальный адрес области ОП, куда будет передаваться информация, и размер передаваемого блока. Запрос на передачу «память – память» подается на канал 0. Получив этот запрос КПДП за один цикл шины считывает из ОП байт, адрес которого он берет из канала 0, и помещает его в свой внутренний регистр временного хранения. Затем КПДП формирует второй цикл шины, в котором этот байт записывается в ОП, по адресу, взятому из канала 1. После этого производится автодекремент счетчика байт и автоинкремент (или автодекремент) адресов в каналах 0 и 1. И так далее.
При передаче «память – память» можно использовать режим автофиксации, при котором в процессе передачи адрес в канале 0 не меняется. То есть этот режим позволяет заполнять заданную область памяти константой.
Режим «память – память» используется, например, для регенерации динамического ОЗУ.
Обычно по окончании передачи блока канал надо перепрограммировать. Однако, если канал настроен на автоинициализацию, перенастройка канала не требуется, поскольку канал автоматически перезагружается исходными данными.
Во избежание конфликтных ситуаций, всем каналам КПДП присваивается приоритет. По умолчанию старший приоритет имеет канал 0, однако мы можем программно изменять приоритеты каналов.
На рис. 26 приведено обозначение ВТ37 на функциональных схемах.
Рассмотрим вкратце назначение входов/выходов ВТ37.
CLK – вход синхроимпульсов, синхросерия подается с генератора ГФ84, КПДП использует эту синхросерию, находясь в режиме ПДП, для формирования циклов шины.
CS – выбор кристалла, нужен в режиме программирования, активный сигнал на этом входе означает что процессор обращается к одному из внутренних регистров КПДП. В режиме ПДП вход CS блокируется.
RESET – сброс. По этому сигналу все каналы переводятся в режим программирования. Все каналы при этом маскируются, то есть запрещается восприятие запросов от ВУ по линиям DREQ 3-0. Поэтому после программирования канала последний надо демаскировать.
READY – готовность. Аналогичен одноименному входу ВМ86. Используется в режиме ПДП. С помощью этого входа синхронизируется работ КПДП и медленнодействующих ОП и или ВУ.
HLDA – подтверждение захвата. Сигнал на этот вход заводится с одноименного выхода МП. Когда на HLDA приходит активный сигнал, КПДП берет управление системной шиной на себя.
IOR и IOW – в режиме программирования это входы. Сигналы на них задают КПДП вид операции, с которой обращается к нему МП. В режиме ПДП это выходы. На них КПДП выставляет сигналы, задающие вид операции порту ВУ.
DREQ 3-0 (DMA request) – входы запросов на ПДП для каналов 3-0. Активный уровень этих сигналов задается при программировании.
А3-0 и А7-4 – на этих линиях в режиме ПДП контроллер формирует младший байт адреса ОП. Адрес на этих линиях стоит до конца цикла шины и его не надо запоминать во внешнем регистре. В остальное время линии А3-0 являются входами. Комбинация сигналов на этих входах задает внутренний регистр КПДП. То есть внутри КПДП имеется шестнадцать адресуемых устройств.
D 7-0 – линии адрес/данные. В режиме ПДП в такте Т1 контроллер выставляет на эти линии старший байт адреса ОП. В такте Т2 адрес с этих линий снимается, поэтому его надо фиксировать во внешнем регистре. В остальное время эти линии представляют собой двунаправленную шину данных.
Из вышеизложенного следует, что ВТ37 вырабатывает 16-ти разрядный адрес и может адресовать только 64 Кбайт памяти. Для того, чтобы КПДП мог адресовать 1 Мбайт, в систему вводят страничные регистры (по одному на каждый используемый канал). В эти регистры программист заранее загружает четыре старших разряда адреса. Чтобы обратиться к другой области памяти, надо сменить содержимое страничного регистра.
ADSTB – сигнал, сопровождающий выдачу адреса. Используется для фиксации старшего байта адреса, формируемого на линиях D 7-0 во внешнем регистре.
AEN (address enable) – активный сигнал на этот выход выставляется в режиме ПДП. Обычно этот сигнал используется для блокирования доступа к шине со стороны других устройств системы.
EOP (end of process) – конец операции. Активный сигнал на этом выходе устанавливается, когда счетчик байт канала переходит через ноль. Этот сигнал может оповещать ВУ об окончании передачи. Линия EOP может использоваться и как вход. Если в режиме ПДП внешним образом сформировать на этой линии активный (нулевой) сигнал, передача прекращается.
HRQ (hold request) – запрос на захват. Подается на вход HOLD МП, отключая последний от системной шины.
MR и MW – сигналы на этих выходах в режиме ПДП задают вид операции для ОП.
DACK 3-0 (DMA acknowledge) – подтверждение ПДП для каналов 3-0. Используются для подключения портов ВУ к шине данных. Активный уровень сигнала на этих выходах задается при программировании контроллера.
В IBM PC/XT стоит один КПДП ВТ37. Его регистрам присвоены системные адреса 00h –0fh. Страничные регистры (порты) в ХТ имеют системные адреса:
81h - для канала 2;
82h – для канала 3;
83h – для канала 1;
87h – для канала 0.
Начиная с PC/AT, в системе стоят два ВТ37, соединенных каскадно.
Рис. 26
2.20 Программирование КПДП ВТ37
Часть внутренних регистров ВТ37 имеют формат восемь бит, другая часть – 16 бит. Для того, чтобы по восьмиразрядной шине загрузить 16 разрядный регистр, требуется две передачи. Перед началом загрузки (или считывания) 16 битного регистра ВТ37, необходимо программным образом установить в ноль триггер «старший/младший», находящийся внутри ВТ37.
Системные адреса 0h, 2h, 4h и 6h выделены 16 разрядным регистрам адреса, соответственно канала 0, канала 1 и. т. д.
Системные адреса 1h, 3h, 5h и 7h присвоены счетчиком байт соответствующих каналов. По этим адресам загружаются размеры передаваемых блоков (число байт в блоке минус 1). Счетчики имеют формат 16 бит, но максимальный размер блока 214.
Все остальные регистры КПДП имеют формат 8 бит.
По адресу 8h загружается командное слово КПДП. Оно относится сразу ко всем каналам и имеет формат, показанный (в упрощенном виде!) на рис. 27.
Рис. 27
D1=1 – режим автофиксации при передаче «память –память».
=0 – нет режима автофиксации.
D0 =1 – режим «память – память».
=0 – нет режима «память – память».
По адресу 0bh производится настройка каналов на режимы работы. Настройка по этому адресу производится для каждого канала. Настроечное слово имеет формат, показанный на рис. 28.
Рис. 28
N1 и N0 задают двоичный номер канала.
D7 и D6 задают режим работы канала (00 – передача по требованию, 01 – одиночная передача, 10 – блоковая передача, 11 – каскадный режим).
D5 =1 – автодекремент адреса.
=0 – автоинкремент адреса.
D4 =1 – есть автоинициализация.
=0 – нет автоинициализации.
D3 и D2 задают направление передачи (01- из ВУ в ОП, 10 – из ОП в ВУ).
Передача любого байта по адресу 0ch, сбрасывает триггер старший/младший.
Передача любого байта по адресу 0dh вызывает программный сброс контроллера (аналогично действию сигнала RESET).
Передача любого байта по адресу 0eh демаскирует все каналы контроллера.
2.21 Организация процессорного модуля ВМ86.
Для того чтобы получить из ВМ86 работоспособный процессор, необходимо реализовать на его основе так называемый процессорный модуль. Последний включает в себя МП ВМ86, генератор ГФ84 и шинный интерфейс, подключающий МП к системной шине.
Подключение генератора ГФ84 производится стандартным образом (смотри рис. 29).
Данная микросхема может работать от внешнего и от внутреннего генераторов. В последнем случае к входам Х1 и Х2 подключается кварцевый резонатор. Сигнал на входе F/C определяет, от какого генератора работает ГФ84. Если на F/C подан нулевой сигнал – от внутреннего, если единичный – от внешнего. Внешний генератор (если он используется) подключается к входу EFI.
Частоты, снимаемые с выходов OSC и PCLK, можно использовать для тактирования внешних устройств.
При работе от внутреннего генератора к входу TANK может быть подключен LC – контур, выделяющий третью гармонику кварца.
Вход CSYNC используется в многопроцессорных системах, в которых к каждому процессору подключен свой ГФ84. При этом с помощью простой внешней схемы, вырабатывающей сигнал на входы CSYNC всех генераторов, обеспечивается их фазовая синхронизация.
Сигнал RESET (сброс) должен поступать на процессор при включении питания и при нажатии кнопки «Сброс». Временные характеристики этого сигнала обеспечивает внешняя схема, формирующая сигнал на вход RESIN.
ГФ84 формирует сигнал готовности (READY) в соответствии с выражением:
READY = AEN1&RDY1 AEN2&RDY2.
Под шинным интерфейсом будем понимать совокупность внешних схем, обеспечивающих подключение ВМ86 к системной шине управления, системной шине данных и системной шине адреса.
Для подключения ВМ86 к ШУ необходимо поставить внешнюю логику, формирующую системные сигналы MR, MW, IOR и IOW, поскольку сам ВМ86 таких сигналов не вырабатывает.
Рис. 29
Схема, формирующая указанные сигналы приведена на рис. 30.
Здесь сигнал BUSEN (bus enable – “шина доступна” ) – системный управляющий сигнал, обеспечивающий блокировку доступа к СШ. В качестве этого сигнала можно, например, брать сигнал с выхода AEN контроллера прямого доступа к памяти ВТ37.
Конечно, рассмотренные четыре сигнала не исчерпывают шину управления. Кроме них по ШУ передаются сигналы INT, INTA, HRQ, HLDA и другие. Однако эти сигналы обычно не требуют для своего формирования каких-либо внешних схем, а снимаются непосредственно с выходных линий ВМ86, ВТ37, ВН59 и других БИС.
Нагрузочная способность выходных линий ВМ86 весьма мала. Поэтому для организации системной шины данных на соответствующие выходы ВМ86 ставятся шинные формирователи (ШФ). На них возлагаются две задачи: увеличить нагрузочную способность линий AD 15-0 и обеспечивать отключение МП от ШД, когда по ШД нет передачи информации. Обычно в качестве ШФ используются восьмиразрядные микросхемы К580ВА86. организация ШД на этих микросхемах показана на рис. 31. Активный (нулевой) сигнал на выходе DEN ВМ86, стробирующий передачу информации по ШД, подключает ШФ к ШД и линиям AD ВМ86. Сигнал на входе Т определяет направление передачи информации через ШФ:
• при Т=1 передача производится от входов А к выходам В;
• при Т=0 передача производится от входов В к выходам А.
Для организации системной шины адреса используются внешние регистры-защелки. В них защелкивается вырабатываемый МП адрес ОП или порта ВУ. При этом преследуется две цели: демультиплексировать шину адрес/данные и сохранить адрес до конца текущего цикла шины. Кроме того,
Рис 30.
регистры позволяют отключать МП от ША, например, при прямом доступе к памяти. Всего в регистрах приходится запоминать 21 бит информации (20 адресных сигналов и сигнал BHE). Для указанных целей обычно используются восьмиразрядные регистры К1810ИР82. Один из вариантов организации ША на этих микросхемах показан на рис. 32.
Рис. 31
рис. 32
2.22. Организация шинного интерфейса в максимальном режиме
Максимальный режим применяется в следующих трех случаях:
• МП стоит в сложной однопроцессорной системе;
• МП стоит в многопроцессорной системе и является ведущим, а остальные процессоры (например, арифметический сопроцессор ВМ87) – ведомыми. Это, так называемая, сильно связанная конфигурация.
• МП стоит в многопроцессорной системе, в которой несколько равноправных процессоров разделяют между собой системную шину. Это, так называемая, слабо связанная конфигурация.
Организация шины данных и шины адреса в максимальном режиме ничем не отличается от их организации в минимальном режиме, а вот организация шины управления имеет существенные отличия. Дело в том, что в максимальном режиме ВМ86 не вырабатывает некоторые необходимые в системе управляющие сигналы. Задача выработки этих сигналов возлагается на специальную микросхему системного контроллера К1810ВГ88 (i8288). Данная микросхема приведена на рис. 33. Далее рассмотрим назначение входов-выходов этой микросхемы.
На входы S2-S0 подаются сигналы состояния с одноименных выходов ВМ86. Эти сигналы характеризуют текущий цикл шины (см. табл.2) и именно по ним контроллер определяет какие управляющие сигналы он должен в данный момент вырабатывать.
На вход CLK подается синхросерия с одноименного выхода генератора ГФ84. По этой синхросерии контроллер определяет момент выдачи управляющих сигналов.
На выходе MRDC (memory read command) контроллер формирует системный управляющий сигнал «чтение из памяти» (MR), а на выходе MWTC (memory write command) – системный управляющий сигнал «запись в память» (MW).
На выходе AMWTC (advanced memory write command) формируется опережающий сигнал «запись в память». Он вырабатывается на один такт ранее сигнала MW и его можно использовать для подготовки к записи медленнодействующих микросхем памяти.
На выходе IORC (input-output read command) контроллер формирует системный управляющий сигнал «чтение из порта ВУ» (IOR), а на выходе IOWC (input-output write command) – системный управляющий сигнал «запись в порт ВУ» (IOW).
Рис. 33
На выходе AIOWC (advanced input-output write command) контроллер формирует опережающий сигнал «запись в порт ВУ». Он вырабатывается на такт ранее IOW и его можно использовать для подготовки ВУ к записи.
Сигнал на выходе ALE (см. одноименный выход ВМ86) определяет момент записи адреса в регистры-защелки ИР82.
Сигнал на выходе DT/R (см. одноименный выход ВМ86) задает направление передачи информации через шинные формирователи ВА86.
Сигнал, снимаемый с выхода DEN (см. одноименный выход ВМ86), подключает шинные формирователи ВА86 к шине данных. Активный уровень сигнала на этом выходе контроллера противоположен активному уровню сигнала на выходе DEN ВМ86, поэтому перед подачей на шинные формирователи сигнал, снимаемый с выхода DEN ВГ88, надо проинвертировать.
INTA – выход подтверждения прерывания (см. одноименный выход ВМ86).
AEN, CEN (command enable – «команда разрешена») и IOB (input-output bus – «резидентная шина ввода-вывода») - управляющие входы контроллера. Если на входе AEN стоит активный нулевой сигнал, контроллер вырабатывает выходные сигналы, если пассивный (единица) – не вырабатывает. Вход CEN действует аналогично входу AEN, только активный сигнал на CEN имеет уровень «единица». Иначе говоря, чтобы ВГ88 вырабатывал выходные сигналы, надо обеспечить AEN=0 и CEN=1. Исключением является случай, когда на вход IOB подана единица. В последнем случае ВГ88 формирует сигналы на выходах IORC, IOWC, AIOWC и PDEN вне зависимости от уровней сигналов на входах AEN И CEN.
Комбинация сигналов на входах AEN, CEN и IOB задает контроллеру конфигурацию системы, в которой работает «его» процессор. В частности, жестко заданная комбинация AEN = IOB = 0, CEN = 1 означает что ВГ88 всегда вырабатывает выходные сигналы. Значит МП стоит в однопроцессорной системе и не разделяет СШ с другими процессорами.
Сигнал на выходе MCE/PDEN (master cascade enable/periphery data enable) трактуется в зависимости от уровня сигнала на входе IOB. Если на IOB подан ноль, сигнал на выходе MCE/PDEN рассматривается как сигнал MCE. Этот сигнал используется если в системе имеет место каскадное подключение контроллеров прерываний ВН59. Если IOB=0, сигнал на выходе MCE/PDEN рассматривается как сигнал PDEN. Назначение сигнала PDEN рассматривается ниже.
2.23. Слабо связанные конфигурации.
В многопроцессорных системах с несколькими равноправными процессорами любой из них может иметь доступ к одной или более шинам. Одна из этих шин, как мы знаем, называется системной (общей). К этой шине имеют доступ все процессоры системы. К системной шине подключается память, но необязательно вся память системы и , возможно, внешние устройства или часть этих устройств. Ресурсы, подключенные к СШ, разделяются всеми процессорами системы. Подключение процессоров к СШ производится через шинные интерфейсы, рассмотренные выше. Управляющие сигналы, подключающие тот или иной ШИ к СШ, вырабатываются специальными схемами арбитров шин.
В любой конкретный момент времени с системной шиной может работать только один процессор. Поэтому для повышения эффективности системы и сокращения простоев процессоров в систему вводятся шины, которые называют резидентными. В многопроцессорной системе резидентной называется шина, к которой имеет доступ только один процессор.
Каждый процессор в многопроцессорной системе может иметь «свою» резидентную шину (РШ). В принципе, процессор может иметь несколько резидентных шин, но такой вариант используется крайне редко.
Если к резидентной шине подключены все внешние устройства, с которыми работает данный процессор и не подключена память, такая шина называется резидентной шиной ввода-вывода (РШВВ).
На практике наиболее часто используются следующие варианты:
• процессор стоит в многопроцессорной системе и имеет доступ только к СШ;
• процессор имеет доступ к СШ и РШ;
• процессор имеет доступ к СШ и РШВВ.
Структурная схема варианта, когда процессор имеет доступ только к СШ, приведена на рис. 34. Здесь и далее показан только один процессор, остальные процессоры системы подразумеваются. Шинный интерфейс (ШИ), как и ранее, включает в себя регистры-защелки ИР82, шинные формирователи ВА86 и системный контроллер ВГ88. IOB, CEN и AEN – управляющие входы системного контроллера. Когда арбитр шин предоставляет процессору доступ к СШ, он формирует активный сигнал на вход AEN контроллера. Последний начинает вырабатывать выходные сигналы, и процессор подключается к СШ.
Структурная схема варианта, при котором процессор имеет доступ к СШ и РШ, показана на рис. 35. Здесь ШИ2 подключает процессор к РШ при наличии активного сигнала на своем входе CEN, ШИ1 подключает процессор к СШ при наличии активных сигналов на своих входах AEN и CEN. Сигналы на входы CEN ШИ1 и ШИ2 формирует дешифратор адреса, который и определяет, к какой шине обращается процессор.
Рис. 34
Структурная схема варианта, при котором процессор имеет доступ к СШ и РШВВ, приведена на рис.36. В отличие от схемы, приведенной на рис. 35, здесь на два шинных интерфейса используется один системный контроллер ВГ88. То есть ШИ2 состоит только из регистров ИР82 и шинных формирователей ВА86. Когда процессор выполняет команду in или out, он обращается к РШВВ, так как именно к ней подключены все ВУ. Системный контроллер ВГ88, независимо от значений сигналов на входах AEN и CEN, формирует выходные сигналы IOR и IOW, являющиеся управляющими для РШВВ. Кроме этого ВГ88 формирует сигнал PDEN, который подключает к РШВВ шинные формирователи ВА86, входящие в состав ШИ2. Подключение процессора к СШ происходит при приходе активного сигнала на вход AEN контроллера ВГ88.
Рис 35
2.24. Арбитр шин К1810ВБ89 (i8289).
Данные микросхемы используются в многопроцессорных системах, в которых несколько процессоров разделяют между собой системную шину. При этом схемы арбитража должны разрешать конфликтные ситуации, возникающие при одновременной попытке доступа к СШ со стороны нескольких процессоров.
Каждому процессору, имеющему доступ к СШ, ставится в соответствие свой арбитр шин. В его задачу входят следующие действия:
Рис.36
• арбитр должен определить, нуждается ли «его» процессор в системной шине, и, если нуждается, обеспечить ему доступ к шине;
• доступ процессора к шине арбитр обеспечивает, вырабатывая активный (нулевой) сигнал на своем выходе AEN. Этот сигнал заводится на одноименный вход системного контроллера ВГ88, входящего в состав шинного интерфейса (см. два предыдущих раздела), и тем самым подключает процессор к системной шине;
Если системная шина свободна или занята процессором с более низким приоритетом, арбитр обеспечит доступ к шине практически сразу. Если же шина занята процессором с более высоким приоритетом, арбитр будет вынужден ждать, пока не наступят условия освобождения шины. Вместе с арбитром в этом случае должен ждать и процессор. Для того чтобы заставить процессор ожидать какое-либо событие, надо сформировать нулевой сигнал на его вход READY. Для этих целей сигнал с выхода AEN арбитра заводится на вход AEN1 (или AEN2) генератора ГФ84. В результате ГФ84 будет формировать нулевой сигнал READY, во всяком случае до тех пор, пока сигнал на выходе AEN арбитра будет оставаться пассивным.
Захватив шину, арбитр никогда ее не освобождает по собственной инициативе. Освобождение шины происходит либо при общем сбросе системы, либо по запросу от другого арбитра. Причем в последнем случае арбитр освобождает шину только если соблюдаются так называемые условия освобождения.
На рис. 37 показано стандартное подключение микросхемы ВБ89.
Рис. 37
Далее вкратце рассмотрим назначение входов/выходов арбитра ВА86.
S2 – 0 - на эти входы заводятся сигналы состояния, характеризующие цикл шины, который выполняет МП (см. табл. 2). По этим сигналам арбитр определяет, нуждается ли МП в шине или нет.
CLK – импульсы, поступающие на этот вход с одноименного выхода генератора ГФ84, синхронизирует работу арбитра и МП.
BCLC (bus CLK) – на этот вход подаются импульсы с генератора шины. Входы BCLK всех арбитров объединяются между собой. Вход служит для синхронизации работы всех арбитров в системе.
INIT - инициализация (сброс). Этот сигнал заводится на все арбитры системы и после его поступления шина будет свободна.
Пока на входе LOCK арбитра стоит активный сигнал, арбитр ни при каких условиях не отдаст шину другому арбитру.
ANYRQST – «любой запрос». Если на этом входе активный сигнал, арбитр отдает шину по любому запросу от другого арбитра.
CBRQLCK - «блокировать вход CBRQ». Этот сигнал запрещает арбитру отдавать шину по запросам с более низким приоритетом.
AEN – активный сигнал на этом выходе означает, что арбитр обеспечил «своему» МП доступ к системной шине.
Для предотвращения конфликтов из-за доступа к СШ всем арбитрам в системе присваивается приоритет. Возможны разные схемы обработки приоритетов. Наиболее простой является последовательная обработка приоритетов (рис. 38). Здесь АШ – арбитр шин.
Рис 38
Если на входе BPRN (bus priority in) АШ стоит единичный сигнал, это означает, что шину удерживает арбитр с более высоким приоритетом. При этом АШ вырабатывает единичный сигнал на выходе BPRO (bus priority out), то есть передает эту информацию менее приоритетным арбитрам (см. рис. 38)
Если АШi потребуется шина и на его входе BPRN стоит нулевой сигнал, этот АШ получит доступ к шине. При этом АШi вырабатывает единичный сигнал на своем выходе BPRO, запрещая доступ к шине арбитрам с более низким приоритетом. Очевидно, что таким путем можно получить доступ к СШ если она свободна или удерживается арбитром с более низким приоритетом.
Пусть АШi требуется доступ к шине, а последняя удерживается арбитром с более высоким приоритетом, то есть на входе BPRN АШi стоит единица. В этом случае АШi выставляет активный (нулевой) сигнал на линию CBRQ (common bus request –«общий запрос шины»), сообщая тем самым арбитру, удерживающему шину, что шина требуется арбитру с более низким приоритетом. При этом удерживающий шину арбитр освободит последнюю, если наступят условия освобождения шины. Рассмотрим далее условия освобождения и удержания шины арбитром АШi:
1. LOCK = 0 – удержание шины;
2. LOCK = 1, BPRN = 1 – безусловное освобождение шины;
3. LOCK = 1, BPRN = 0, ANYRQST = 1, CBRQ = 0 – безусловное освобождение шины;
4. LOCK = 1, CBRQLCK = 0, CBRQ = 0 – удержание шины;
5. LOCK = 1, BPRN = 0, CBRQLCK = 1, CBRQ = 0 – условное освобождение шины.
При условном освобождении удерживающий шину арбитр освободит ее когда «его» процессор начнет выполнять команду hlt или nop.
Когда АШi получает доступ к шине, он выставляет нулевой сигнал на линию BUSY («занят»), сообщая другим арбитрам, что шина занята.
Схема последовательной обработки приоритетов (рис. 38) не требует дополнительного оборудования, однако имеет существенный недостаток, заключающийся в том, что в цепочку можно соединить не более трех арбитров. Для устранения этого недостатка используются более сложные схемы параллельной обработки приоритетов, в которых задействуются выходы BREQ (bus request – «запрос шины») арбитров. При этом в систему приходится вводить внешние логические схемы, которые и обеспечивают параллельную обработку приоритетов.
Сигналы на выходах IOB (input-output bus), RESB (residential bus) и SYSB/RESB (system bus / residential bus) задают конфигурацию системы. В соответствии с ними арбитр трактует сигналы на входах S2-S0, определяя нуждается «его» МП в шине или нет. Наиболее часто используются следующие конфигурации:
1. IOB = 1, RESB = 0 (SYSB/RESB – безразлично) – МП, которому соответствует данный арбитр, работает только с системной шиной (см. рис. 34);
2. IOB = 0, RESB = 0, SYSB/RESB = 0 – МП работает с СШ и РШВВ. К какой из этих шин обращается МП, арбитр определяет по сигналу на входе S2. При S2=0 – к РШВВ, при S2 = 1 – к СШ ( см. табл. 2).
3. IOB = 1, RESB = 1 –МП работает с СШ и РШ. К какой из этих шин обращается МП, определяет сигнал на входе SYSB/RESB (SYSB/RESB =1 – к СШ, SYSB/RESB = 0 – к РШ). Этот сигнал снимается с выхода дешифратора адреса (см. рис 35).
2.25 Сильно связанные конфигурации на примере совместной работы МП86 и арифметического сопроцессора ВМ87.
Арифметический сопроцессор предназначен для выполнения сложных арифметических команд. МП и сопроцессор вместе образуют многопроцессорную систему, в которой МП является ведущим, а сопроцессор – ведомым. Поскольку в этом случае процессоры не являются равноправными, арбитр шин здесь не нужен.
Сопроцессор «не умеет» формировать адреса и считывать из ОП команды. За него это делает МП. Однако сопроцессор может производить обмен информацией с ОП, используя при этом адреса, сформированные МП. Стандартное соединение ВМ86 и ВМ87 приведено на рис 39.
Рис. 39
После прихода сигнала RESET (сброс) сопроцессор анализирует сигнал на линии BHE, выясняя с каким МП он работает. Для ВМ86 на этой линии в первый момент будет ноль, а для ВМ88 – единица. После этого сопроцессор переходит в пассивное состояние.
МП читает из оперативной памяти команды и заносит их в свою внутреннюю очередь. Сопроцессор эти команды перехватывает и также заносит их в свою внутреннюю очередь. В любой момент времени ситуация в обеих очередях должна быть одинаковой, поэтому сопроцессор следит за изменениями в очереди МП по линиям QS 1-0.
Когда ВМ87 перехватывает команду, являющуюся командой сопроцессора, он начинает переходить в активный режим. Полностью активным он становится, когда МП начинает выполнять «его» команду.
Система команд сопроцессора включает в себя более 80 команд, однако МП воспринимает все их как одну команду esc (escape). С точки зрения МП имеется три разновидности этой команды.
1. Команда работает с внутренними регистрами сопроцессора и не требует обращения к ОП. ВМ86 и ВМ87 одновременно начинают выполнение этой команды. При этом ВМ86 выполняет ее как команду nop (no operation) и переходит к выполнению следующей команды программы, а ВМ87 продолжает правильное выполнение заданной команды. То есть далее оба процессора работают параллельно.
2. Команда читает операнд из ОП и заносит его во внутренний регистр сопроцессора. При выполнении такой команды ВМ86 формирует адрес операнда в ОП и выставляет его на ША. Там этот адрес перехватывает сопроцессор и заносит его в свой специальный внутренний регистр. Из ОП по выставленному адресу считывается слово, которое сопроцессор принимает, а МП игнорирует. Далее МП переходит к выполнению следующей команды программы. Операнды сопроцессора занимают в памяти до 10-ти байт, поэтому оставшийся «хвост» операнда сопроцессор должен считать самостоятельно. Для этих целей сопроцессор запрашивает у МП шину по линии RQ/GT и считывает остаток операнда из ОП, используя перехваченный адрес.
3. Команда заносит в память содержимое внутреннего регистра сопроцессора. ВМ86 вырабатывает адрес, который перехватывает сопроцессор. По этому адресу из ОП считывается слово, которое на этот раз игнорируют оба процессора. Затем ВМ87 запрашивает шину по линии RQ/GT и производит запись в ОП, используя перехваченный адрес.
Команды сопроцессора достаточно сложны и для их выполнения требуется много времени. Поэтому высока вероятность того, что к началу выполнения следующей команды сопроцессора последний не успеет завершить выполнение предыдущей команды. Поэтому перед командами сопроцессора в программах рекомендуется ставить команду wait («ждать»). Эта команда проверяет сигнал на входе TEST и, если там стоит единица, МП ждет, пока на входе TEST не появится ноль. Сигнал на вход TESY заводится с выхода BUSY («занят») сопроцессора. При этом если на BUSY стоит единица, значит ВМ87 занят выполнением команды.
2.26. Формат машинной команды ВМ86.
Машинная команда микропроцессора 8086 имеет формат, приведенный на рис. 40.
Рис. 40
Префикс – это байт, идущий перед командой и несколько меняющий ее смысл. Для МП 8086 допустимы: префикс блокировки, префикс замены сегмента и префикс повторения. В большинстве команд префиксы отсутствуют, однако, в команде могут использоваться и все три префикса одновременно. Префикс блокировки (lock) имеет значение 11110000. Префикс замены сегмента имеет формат 011sr110. Здесь поле sr задает сегментный регистр, который используется в команде (табл.6). Префикс повторения (rep) имеет значение 11110011 (или в еще одном варианте 11110010).
Таблица 6.
11110010).
Поле КОП – единственное из полей, которое всегда присутствует в команде. Занимает это поле, в зависимости от команды, один или два байта. Младший бит этого поля (w) в большинстве случаев задает разрядность операции. При w=0 команда работает с байтом, при w=1 – со словом.
Постбайт либо в команде отсутствует, либо занимает один байт. Это поле задает регистры, которые принимают участие в формировании адресов операндов. Формат постбайта приведен на рис.41.
Рис. 41
Поле reg (регистр) задает регистр в двухоперандных командах (табл. 7). Аналогично трактуется поле rm (регистр/память) при md=11 (mode – «режим»). При других значениях md, поле rm задает способ формирования адреса памяти (табл. 8).
Поле disp (dispersion – «смещение») задает смещение при базовой адресации (или адрес при прямой адресации) и может занимать 0, 1 или 2 байта.
Поле data («операнд») присутствует, если в команде используется непосредственная адресация.
Таблица 7.
Таблица 8.
Например, команда lock add cs: [bp+ di+100h], 77h имеет шестнадцатеричное представление: F0 2E 80 83 0010 77 ( F0 – младший байт в ОП). Здесь F0 – префикс блокировки (lock), 2E –префикс замены сегмента (cs: ), 80 – код команды (операции) (add), 83 – постбайт (задает способ формирования адреса: bp+di+disp), 0010 – смещение (100h) и 77 – непосредственный операнд.
3. 32-х РАЗРЯДНЫЕ ПРОЦЕССОРЫ ФИРМЫ INTEL.
3.1. Знакомство с терминологией
Данный раздел пособия предназначен для ознакомления читателя с основными терминами, используемыми при описании микропроцессоров с 32-х разрядной архитектурой. Вся изложенная в данном разделе информация будет в дальнейшем рассмотрена более подробно.
Среди 32-х разрядных процессоров фирмы INTEL различают процессоры 386, 48б, Pentium, семейство Р6 (процессоры Pentium Pro, Pentium II, Celerone и Pentium III, в котрых фирма реализует микроархитектуру Р6) и Pentium 4, в котором реализована, так называемая, NetBurst микроархитектура. При этом базовые механизмы, реализуемые всеми этими процессорами практически (за исключением нюансов) идентичны. Поэтому далее при употреблении термина «процессор» речь будет идти обо всех вышеперечисленных процессорах одновременно, а конкретные особенности для каждого отдельного процессора будут оговариваться дополнительно.
Итак, процессор имеет 32 адресных линии (А31-0) и, следовательно, может адресовать 232 байт (4 Гбайта) оперативной памяти. Начиная с Р6 в регистре cr4 (control register – «регистр управления») введен специальный бит PAE (physical address extension – «расширение физического адреса»). Если этот бит установлен в единицу к процессору добавляются еще 4 адресные линии (А35-32) и он может адресовать 64 Гбайта оперативной памяти. Правда при этом обязательно должен быть включен страничный механизм. Связано это с тем, что, несмотря на наличие 36-ти адресных линий, сегментный механизм процессора продолжает вырабатывать 32-х разрядный адрес, то есть продолжает адресовать 4 Гбайта ОП. И только наличие страничного механизма позволяет транслировать эти 4 Гбайта в любое место 64-х Гбайтного пространства. Подробно этот механизм будет рассмотрен в дальнейшем.
Шина данных у 386 и 486 32-х разрядная, начиная с Pentium – 64-х разрядная. При этом во всех процессорах (в отличие от ВМ86) шины адреса и данных раздельные (не мультиплексные!!).
Процессор может работать в следующих режимах:
1) РЕАЛНЫЙ РЕЖИМ. С точки зрения пользователя МП в этом режиме представляет из себя аналог МП 8086, только более быстрый и с расширенной системой команд. Механизм формирования физического адреса в реальном режиме аналогичен подобному механизму МП 8086 :
Аф = (sr)×16 + Аэф.
Хотя здесь надо отметить что сами процессы формирования Аф в 8086 и реальном режиме различны, а вот результат будет один и тот же.
Так как сегментные регистры (sr) и Аэф - 16-ти разрядные, формируемый таким образом Аф будет 20-ти разрядным. Следовательно в реальном режиме МП адресует 1Мбайт оперативной памяти (младший мегабайт 4-х Гбайтного пространства памяти). Сегменты, как и в ВМ86 имеют фиксированный размер 64Кбайта.
2) Режим виртуального 86-го процессора (V86). Этот режим предназначен для того, чтобы в защищенном режиме у нас была возможность выполнять программы, написанные для ВМ86 (DOS задачи). Работа процессора в этом режиме похожа на работу ВМ86, но сам режим V86 является подмножеством защищенного режима.
3) Режим SMM (system management mode –«режим управления системой»). Работа процессора в этом режиме «не видна» ни прикладным программам, ни даже операционной системе. Связано это с тем, что в этом режиме процессор адресует область памяти недоступную в других режимах. Обычно в этом режиме процессор выполняет программу, написанную разработчиками аппаратуры. Чаще всего эта программа реализует системные функции пониженного энергопотребления. Попасть в режим SMM можно только по специальному внешнему аппаратному прерыванию SMI (system mode interrupt). Выход из режима SMM осуществляется специальной командой RSM (resume system mode).
4) ЗАЩИЩЕННЫЙ РЕЖИМ. В этом режиме раскрываются все возможности МП. В этом режиме используются все 32 адресных линии и следовательно может адресоваться память объемом до 4 Гбайт. Сегменты в защищенном режиме имеют переменный объем (от 1 байта до 4 Гбайт). Одновременно МП может работать с 214 таких сегментов. Очевидно что все эти сегменты могут не поместиться в реально существующей оперативной памяти (ОП), поэтому часть из них (а скорее всего большинство) находится на диске. Когда процессор обращается к сегменту, которого нет в ОП происходит прерывание. Обработчик этого прерывания должен подкачать с диска в ОП нужный сегмент, после чего происходит рестарт «виноватой» команды. От пользователя этот процесс скрыт и у него создается впечатление что в его распоряжении находится память объемом 64 Тбайта (214 сегментов по 4 Гбайта каждый, то есть 246 байт). Такая память называется виртуальной (кажущаяся).
В защищенном режиме МП аппаратным образом поддерживает многозадачность. То есть в системе одновременно может находится множество задач, а МП обеспечивает быстрое переключение между этими задачами. Наличие многозадачности приводит к ряду проблем, основные две из которых:
• как переключаться с задачи на задачу;
• как защитить задачи друг от друга.
Для решения первой проблемы для каждой задачи в системе создается так называемый «сегмент состояния задачи» (TSS – task state segment). Размер этого сегмента должен быть не менее 104-х байт. Когда МП переключается с задачи А на задачу В он автоматически запоминает контекст задачи А (содержимое почти всех своих внутренних регистров) в TSS задачи А, а затем также автоматически загружает в свои регистры контекст задачи В (из TSS задачи В). Тем самым обеспечивается переключение на задачу В и в то же время возможность возврата и продолжения выполнения задачи А. Вообще под задачей понимается любой программный код, для которого в системе создан свой TSS. Создание TSS -это функция операционной системы.
Для решения проблемы защиты задач друг от друга всем создаваемым в системе сегментам присваивается уровень привилегий. Всего возможно четыре уровня привилегий: 0,1,2 и 3, причем 0-й уровень самый старший. Уровень 3 (самый низкий) присваивается обычно сегментам пользователя, уровень 0 - сегментам ОС, а уровни 1 и 2 предназначены для расширения ОС и на практике зачастую не используются .
Когда программа с уровнем привилегий А обращается к сегменту с уровнем привилегий В процессор проверяет условие А <= В. Если это условие выполняется доступ к сегменту будет предоставлен, если же условие не выполняется будет прерывание (нарушены права доступа к сегменту).
Механизм формирования физического адреса в защищенном режиме радикально отличается от механизма МП 8086. Для каждого создаваемого в системе сегмента создается ( как правило ОС) специальная структура, называемая дескриптором этого сегмента. Дескриптор занимает в памяти 8-мь байт и содержит все необходимые сведения о сегменте: начальный адрес сегмента, размер сегмента, уровень привилегий, атрибуты сегмента и.т.д. МП вычисляет физический адрес по формуле:
Аф = начальный адрес сегмента + Аэф.
При этом, в отличии от 8086, начальный адрес сегмента не вычисляется, а берется готовым из дескриптора.
Все созданные в системы дескрипторы сводятся в дескрипторные таблицы. Любая задача может одновременно работать с двумя такими таблицами. Одна из них называется глобальной (GDT (global descriptor table)), а другая - локальной (LDT (local descriptor table)). В GDT собраны дескрипторы сегментов, разделяемых всеми задачами в системе, а в LDT располагаются дескрипторы сегментов, с которыми работает только данная задача. GDT в системе одна и всегда должна находиться в ОП, а LDT может быть столько же сколько и задач (для любой задачи LDT может быть создана, а может и не создаваться) и располагаться эти таблицы могут как в ОП, так и на диске.
Для того чтобы перейти к новому сегменту, надо обратиться к его дескриптору, то есть надо найти этот дескриптор в дескрипторной таблице. Для этого необходимо знать начальный адрес таблицы и внутритабличное смещение (это смещение принято называть селектором дескриптора). Начальные адреса таблиц процессору известны, они хранятся в специальных внутренних регистрах МП, а смещение берется из сегментного регистра. При этом любой сегментный регистр в МП имеет формат, приведенный на рис. 42.
Видимая часть
Теневая часть
16 бит
64 бита
Рис. 42
Видимая часть доступна программисту, а с теневой частью работает сам МП. Видимая часть имеет формат, приведенный на рис. 43.
15 3
2
1 0
селектор
TI
RPL
Рис. 43
Здесь старшие 13 разрядов (биты 15 - 3) занимает селектор, определяющий местоположение дескриптора в одной из двух дескрипторных таблиц ( в какой именно задает бит TI (table indicator)). При обращению к дескрипторной таблице к селектору справа дописываются три нуля и он становится 16-ти разрядным. Дело здесь в том, что размер дескриптора 8 байт и его смещение в таблице всегда кратно восьми. Биты 1 и 0 задают запрашиваемый уровень привилегий (RPL(requested privilege level)). Нетрудно видеть, что максимальное число дескрипторов в любой дескрипторной таблице 213 (поскольку селектор 13-ти разрядный), а максимальный размер таблицы равен 8×213 = 64К. А так как одновременно процессору доступны две такие таблицы то, как уже отмечалось выше, МП одновременно доступны 214 сегментов.
При обращению к новому сегменту в видимую часть сегментного регистра загружается новый селектор. По этому селектору в дескрипторной таблице МП находит дескриптор нового сегмента. Проверяются права доступа (и не только они) и, если они не нарушены, найденный дескриптор копируется (кэшируется) в теневую часть сегментного регистра (с тем чтобы в дальнейшем он был у МП «под рукой» и не требовалось каждый раз обращаться за ним в память). Например. Выполняется команда jmp 0008 : 00000002h. При этом 00000002h –это смещение в новом кодовом сегменте и эта величина будет загружена (если не нарушены права доступа и другие условия) в регистр eip. Величина 0008h представляет из себя селектор, ссылающийся на 1-й дескриптор в GDT (TI = 0, RPL = 0). Смотри рис. 44.
GDT
0-й дескриптор
1-й дескриптор
.
.
.
.
Рис. 44
Очевидно что таким способом (из-за проверки прав доступа) нельзя обратится к более привилегированному сегменту, поскольку при этом будет прерывание (нарушены права доступа). В то же время должна быть возможность обращения к привилегированным сегментам, хотя бы потому, что в противном случае задачам пользователя вообще будут недоступны средства ОС. Для предоставления такой возможности в системе создаются специальные структуры называемые шлюзами (вентилями) (gate).
Шлюз - структура, подобная дескриптору. Так же как и дескрипторы шлюзы занимают в памяти по 8 байт и располагаются в дескрипторных таблицах. Однако, если через дескриптор мы обращаемся к сегменту и при этом проверяется уровень привилегий, записанный в этом дескрипторе (см. рис. 45), то через шлюз мы обращаемся к дескриптору, на который ссылается этот шлюз (и далее через этот дескриптор к сегменту), при этом проверяется уровень привилегий, записанный в шлюзе, а уровень привилегий, записанный в дескрипторе, игнорируется (см. рис. 46). Здесь cpl (current privilege level) - текущий уровень привилегий задачи, dpl (descriptor privilege level) – уровень привилегий сегмента, записанный в его дескрипторе. Уровень привилегий, записанный в шлюзе (dpl шлюза), задает минимальный уровень привилегий, на котором разрешается «проход» через данный шлюз. Отметим также что проверки, приведенные на рис. 45 и рис. 46, для простоты картины показаны несколько упрощенно и даже не совсем корректно, более полно они будут рассмотрены позднее.
Обращаться через шлюзы можно только к исполняемым сегментам. К последним относятся сегменты кода и сегменты TSS.
Рис. 45
Рис. 46
Например, пусть выполняется программа с уровнем привилегий 3. В какой-то момент программа обращается к сегменту, в дескрипторе которого записан уровень привилегий 0. Попытка этого обращения окончится неудачно (прерыванием). Однако, если в системе есть шлюз, ссылающийся на этот дескриптор и имеющий уровень привилегий 3, и нашей программе известно его месторасположение в таблице она может обратиться к этому шлюзу. При этом права доступа для шлюза нарушены не будут и шлюз позволит программе обратиться к дескриптору. Права доступа дескриптора проверяться в этом случае не будут и программа получит доступ к сегменту с уровнем привилегий 0.
Шлюзы бывают четырех типов:
• шлюз вызова. Может располагаться в таблицах GDT и LDT. Предназначен для вызова привилегированных подпрограмм.
• шлюз задачи. Может располагаться в GDT, LDT и IDT (interrupt descriptor table) (дескрипторная таблица прерываний). Предназначен для переключения на привилегированную задачу.
• шлюз прерываний. Может располагаться только в IDT. Служит для вызова обработчика внешнего прерывания. При переходе через этот шлюз флаг if сбрасывается в ноль, то есть запрещаются внешние прерывания.
• шлюз ловушки. Может располагаться только в IDT. Служит для вызова обработчика внутреннего прерывания (особого случая). Практически аналогичен шлюзу прерываний, только внешние прерывания не запрещаются.
Некоторые сегменты кода могут быть отмечены как согласованные (подчиненные) (conforming). Если обычный сегмент кода всегда выполняется на том уровне привилегий, который записан в его дескрипторе, то согласованный сегмент кода выполняется на том уровне привилегий, с которого он был вызван. То есть уровень привилегий, записанный в дескрипторе согласованного сегмента в расчет не принимается и к такому сегменту можно обратиться с любого уровня привилегий. Здесь имеется одно исключение – ни к какому кодовому сегменту, в том числе и согласованному, нельзя обратиться с более высокого уровня привилегий !! Обычно в согласованных сегментах располагаются системные библиотеки. Большинство сегментов в системе, как правило, согласованными не являются.
Зачастую для одного и того же сегмента в системе создаются сразу несколько дескрипторов. Такие дескрипторы называют альтернативными (или псевдонимами) (alias). Например, пусть некоторый сегмент данных разделяется задачей пользователя и ОС. При этом ОС может менять данные в этом сегменте, а задача пользователя может только считывать информацию из этого сегмента. Для того чтобы такая организация была возможна придется создать два дескриптора этого сегмента. В одном сегменту будет присвоен 0-й уровень привилегий и этот сегмент будет описан как доступный для чтения/записи, в другом будет 3-й уровень привилегий и сегмент будет отмечен доступным только для чтения.
3.2. Реальный режим
МП автоматически переходит в этот режим при приходе сигнала RESET (сброс). В реальный режим можно попасть и из защищенного режима если установить в ноль бит PE в регистре cr0 (см. рис. 47).
31 1
PE
cr0
Рис. 47
Сбросить этот бит можно командой mov cr0 , r 32 , где r 32 - любой 32-х разрядный регистр МП. Выполнить такую команду в защищенном режиме можно только находясь на уровне привилегий 0. Если сбросить этот бит «в лоб» мы перейдем в реальный режим, но где мы при этом окажемся неизвестно (скорее всего мы «повесим» систему). Поэтому перед переключением из защищенного режима в реальный требуется большая подготовительная работа со стороны системного программиста с тем чтобы обеспечить реальную точку входа в реальный режим. Вопрос переключения из защищенного режима в реальный будет рассмотрен в дальнейшем, когда у читателя появятся соответствующие знания.
Как уже отмечалось ранее механизм формирования Аф в реальном режиме совпадает с аналогичным механизмом МП 8086. Вернее, совпадает конечный результат (Аф), а сами механизмы отличаются друг от друга.
МП 8086 при обращении внутри текущего сегмента считает Аф по следующей схеме. Сначала он считает Аэф. Затем он берет содержимое соответствующего сегментного регистра и сдвигает его на 4-ре разряда влево (умножает на 16) получая начальный адрес сегмента. К этому начальному адресу МП прибавляет Аэф и получает Аф.
32 разрядный МП в реальном режиме действует несколько иначе. Отличие заключается в том что начальный адрес сегмента рассчитывается здесь не при каждом обращении к данному сегменту, а всего один раз, при загрузке в сегментный регистр новой информации. То есть когда содержимое какого-либо сегментного регистра меняется МП умножает загружаемую в этот регистр информацию на 16-ть и полученный начальный адрес сегмента загружает в теневую часть сегментного регистра. Далее при любом обращении внутри текущего сегмента МП берет готовый начальный адрес сегмента из теневой части соответствующего сегментного регистра. Отсюда можно сделать вывод что механизмы обращения в текущем сегменте в реальном и защищенном режимах в принципе одинаковы, а все различие заключается в механизмах смены сегмента, которые в этих режимах кардинально отличаются друг от друга.
Так же как и МП 8086, 32 разрядный МП в реальном режиме адресует 1Мбайт оперативной памяти (младший мегабайт 4-х гигабайтного пространства защищенного режима). Таблица прерываний в реальном режиме ( так же как в МП 8086) располагается в младшем килобайте ОП. Тут надо отметить, что имеется возможность (в отличие от МП 8086) переместить эту таблицу в другое место памяти, но на практике эта возможность не используется.
Существует еще ряд небольших отличий между 32 разрядным МП в реальном режиме и МП 8086. Далее рассмотрим эти отличия.
1. Система команд 32 разрядного МП значительно шире и большинство этих команд можно использовать в реальном режиме.
2. Добавлено два новых сегментных регистра fs и gs. К ним можно обращаться с помощью префиксов замены сегментов.
3. Внутренние регистры МП 32-х разрядные. Их можно использовать в реальном режиме. То есть допустима, например, команда
mov eax , ebx.
4. 32-х разрядные регистры можно использовать и для формирования Аэф (например, mov al , [esi+2] ). Однако при этом если сформированный Аэф окажется больше 0000ffffh будет прерывание. То есть в отличие от МП 8086 здесь отсутствует кольцевая организация сегментов. Вычислив Аэф МП проверяет (как в реальном, так и в защищенном режимах) не выводит ли этот адрес за заданные границы сегмента. Заданный размер сегмента МП берет из теневой части соответствующего сегментного регистра. При приходе сигнала RESET МП, переходя в реальный режим, автоматически загружает в теневые части всех своих сегментных регистров в качестве размера сегмента величину ffffh. Именно поэтому если Аэф превышает эту величину происходит прерывание. Такая организация приводит к тому что у пользователя (вернее, у системного программиста) появляется возможность заставить МП в реальном режиме адресовать больше 1Мбайта оперативной памяти (вплоть до 4-х Гбайт). Для этого надо переключиться в защищенный режим, обеспечить загрузку в теневые части нужных сегментных регистров дескрипторов, в которых задан соответствующий размер сегмента (например, 10Мбайт) и вернуться обратно в реальный режим. После этого через данные сегментные регистры можно будет обращаться к памяти объемом 10Мбайт (только не надо менять содержимое этих сегментных регистров).
5. При формировании Аф может возникнуть перенос из старшего разряда (из разряда А19 в разряд А20). В МП 8086 этот перенос попросту отбрасывается, в результате получается кольцевая организация памяти. В 32 разрядном МП этот перенос не отбрасывается, а выставляется на адресную линию А20 . Таким образом , в отличие от МП 8086, 32 разрядный МП в реальном режиме адресует не 1Мбайт ( 00000000h - 000fffffh) памяти, а 1Мбайт плюс еще 64Кбайта ( 00000000h - 0010ffefh). Здесь и в тех и в других скобках приводится диапазон адресуемой памяти. Эти дополнительные 64Кбайта памяти называют верхней памятью и активно используют, загружая в нее различные драйверы. В IBM-подобных ПЭВМ предусмотрена возможность реализации кольцевой организации памяти в реальном режиме. Для этого надо замаскировать адресную линию А20. Это можно сделать следующими четырьмя командами:
mov al , 0d1h ;команда управления линией А20
out 64h , al ;передается в статус порт 64h
mov al , 0ddh ;закрыть линию А20
out 60h , al
Для того чтобы открыть эту адресную линию используются такие же четыре команды, только в третей команде вместо 0ddh надо написать 0dfh.
3.3 Переключение в защищенный режим
Процессор переходит в этот режим когда бит PE в регистре cr0 устанавливается в единицу. Установить этот бит можно командами mov cr0 , r 32 или командой lmsw r16 / m16 . Последняя команда загружает из памяти или 16-ти разрядного регистра младшую половину регистра cr0. Обе команды доступны в реальном режиме.
После перехода в защищенный режим МП ожидает наличия в памяти по крайней мере двух таблиц: GDT и IDT. Поэтому эти таблицы должны быть созданы заранее ещё в реальном режиме, например с помощью ассемблерных директив db, dw и dd. Что касается LDT, то её (их) можно создать как заранее в реальном режиме, так и позднее, когда мы уже находимся в защищенном режиме. Зачастую LDT вообще не создаются.
В общем случае переключение в защищенный режим требует серьезной подготовительной работы со стороны программиста, который должен выполнить примерно следующую последовательность действий.
1. Создать в памяти таблицы GDT и IDT.
2. Запретить внешние прерывания, в том числе и по входу NMI (если последний в системе используется). Связано это с тем, что в процессе переключения есть временной интервал когда таблица векторов прерываний реального режима уже не действует, а таблица IDT ещё не действует. Если на этом интервале МП воспримет любое прерывание наступит крах системы.
3. Перенастроить контроллеры прерываний на новые типы (номера) прерываний, с тем чтобы исключить конфликты между внутренними и внешними прерываниями. Собственно этот пункт не имеет никакого отношения к самому МП, а связан с особенностями функционирования IBM-подобных ПЭВМ. Когда фирма Intel выпустила МП 8086 она заняла под внутренние прерывания типы 0 - 4, но предупредила, что типы 5 -31 резервируются для внутренних прерываний будущих процессоров. По каким-то причинам (нам они не известны) фирма IBM это предупреждение проигнорировала и отвела типы 8 - 15 внешним прерываниям. В результате, например, тип 8 присвоен внешнему прерыванию от таймера (этот тип выдает на МП контроллер прерываний) и одновременно в 32 разрядных МП этот тип отведен особому случаю (внутреннему прерыванию) «двойная ошибка». Получается конфликт так как МП не знает какой обработчик он должен выполнять.
4. Открыть линию А20 (если она была закрыта).
5. Во внутренние регистры процессора gdtr и idtr загрузить начальные адреса и размеры таблиц GDT и IDT.
6. Установить бит РЕ. С этого момента мы в защищенном режиме.
7. Обычно первой командой в защищенном режиме ставится команда jmp far next (дальний переход на следующую команду программы). Команда очищает очередь команд от команд защищенного режима, а также заносит в видимую часть cs правильный селектор, по которому в дескрипторной таблице GDT отыскивается дескриптор сегмента кода. Далее этот дескриптор копируется в теневую часть cs. Очистка очереди команд нужна исходя из следующих соображений. Во всех рассматриваемых процессорах реализован конвейер команд. То есть в любой момент времени внутри процессора обрабатывается сразу несколько команд, находящихся на разных стадиях выполнения. Отсюда, при переключении режимов возникает ситуация когда с конвейера еще сходят команды одного режима, а на конвейер уже поступают команды другого режима. Поскольку в разных режимах одни и те же команды выполняются по разному, такая ситуация иногда может приводить к различным коллизиям. Использование команды jmp снимает эту проблему. Начиная с Pentium использование команды jmp, для рассмотренной выше цели, необязательно, поскольку команды, меняющие содержимое регистров управления cr0-cr4, гарантируют, что все команды, идущие перед ними, будут завершены (так называемые «сериалайзд» команды – serialized instruction).
8. Разрешить внешние прерывания.
Не следует считать что все эти пункты всегда обязательны к исполнению, Это только общая схема действий, причем подразумевающая что мы переключаемся в защищенный режим «всерьёз и надолго». Если же требуется только «нырнуть» в защищенный режим и тут же вернуться обратно многие пункты можно исключить. В частности можно не создавать IDT, не загружать IDTR, и вообще не выполнять пункты 3,4 и 7.
Далее приведен пример программы, переключающей процессор из реального режима в защищенный и обратно. Находясь в защищенном режиме программа очищает экран и выводит надпись «МЫ В ЗАЩИЩЕННОМ РЕЖИМЕ». Кроме того, после возврата в реальный режим, программа выводит на экран числовое значения поля TYPE дескриптора видеопамяти (смотри формат дескриптора). Программу надо запускать находясь в «чистой» DOS (без EMM и других подобных драйверов) . Программу можно было написать значительно проще, но здесь преследовалась цель продемонстрировать общие принципы переключения в защищенный режим.
code segment
p486
org 100h
assume cs:code, ds:code
start: jmp begin
mess db ' МЫ В ЗAЩИЩЕННОМ РЕЖИМЕ '
gdt dd 0 ; пустой дескриптор
dd 0
dw 0ffffh ; дескриптор видеопамяти
dw 8000h
db 0bh
db 92h
dw 0
desc_gdt dq 0 ; заготовка под дескриптор GDT
begin:
mov si,offset desc_gdt ; заносим в заготовку размер и адрес GDT
mov word ptr [si],15 ; это размер
mov ebx,0
mov bx,offset gdt
push cs
mov eax,0
pop ax
shl eax,4
add ebx,eax
mov [si+2],ebx ; а это адрес
lgdt pword ptr [si] ; а теперь перекидываем заготовку в GDTR
mov eax,cr0
mov edx,eax
cli
or eax,1
mov cr0,eax ; переключение в защищенный режим
mov ax,8
mov es,ax ; заносим в ES дескриптор видеопамяти
cld
mov di,0 ; чистим экран
mov ax,7020h
mov cx,2000
rep stosw
mov bx,offset mess ; выводим надпись
mov si,1010
mov cx,22
m:
mov al,[bx]
mov es:[si],al
add si,2
inc bx
loop m
mov cr0,edx ; выходим обратно в реальный режим
sti
mov si,1348 ; этот фрагмент доказывает что МП
mov di,offset gdt ; использует в РР начальный адрес
mov al,[di+13] ; из теневой части сегментного регистра,
and al,0fh ; а не из видимой ( в видимой части ES - 8, а значение
add al,30h ; выводится в видеопамять!!) и также показывает, что
mov es:[si],al ; МП сам устонавливает бит А в дескрипторе (было
; 92,стало 93 (на экран выводит-ся 3))
mov ah,7
int 21h
mov ah,4ch
int 21h
code ends
end start
3.4. Системные таблицы
ТАБЛИЦА GDT. Эта таблица создается еще в реальном режиме и содержит следующие виды дескрипторов:
• Дескрипторы сегментов ОС.
• Дескрипторы сегментов, разделяемых несколькими задачами.
• Дескриптор самой GDT, где она описана как сегмент данных ( с тем чтобы мы могли вносить в GDT изменения).
• Дескриптор таблицы IDT, где она описана как сегмент данных (причины те же).
• Дескрипторы всех созданных в системе таблиц LDT .
• Альтернативные дескрипторы для всех LDT, где эти таблицы описаны как сегменты данных.
• Дескрипторы всех сегментов TSS.
• Альтернативные дескрипторы для всех TSS, где TSS описаны как сегменты данных.
• Возможно другие дескрипторы и шлюзы.
Не следует конечно думать что все перечисленные выше дескрипторы должны обязательно присутствовать в GDT. А вот нулевой (самый первый дескриптор в таблице) дескриптор в GDT обязательно должен быть пустым (состоять из одних нулей). Его использует МП для системных целей.
Для того чтобы МП знал где в ОП располагается таблица GDT, внутри МП имеется специальный регистр gdtr: Его формат приведен на рис. 48.
47 16
15 0
начальный адрес GDT
размер GDT
Рис. 48
Размер GDT задается в байтах. Для загрузки этого регистра используется команда lgdt m 40 / m 48. То есть команда загружает в регистр пять или шесть байт из памяти (пять байт здесь используется для совместимости с МП 286, который работал не с 32-х, а с 24-х разрядным адресом). Например, следующая команда загружает в регистр gdtr шесть байт из области памяти, на которую указывает регистр si;
lgdt pword ptr [si].
Команда lgdt допустима как в реальном, так и в защищенном режимах, но в защищенном она доступна только на 0-м уровне привилегий. При первом использовании этой команды (еще в реальном режиме) задается местоположение таблицы в памяти и ее размер. В дальнейшем эта команда может использоваться для изменения размера GDT, например, если понадобилось добавить в GDT новые дескрипторы. Менять местоположение GDT в памяти не имеет никакого смысла (хотя рассматриваемая команда и предоставляет такую возможность).
Таблица GDT в системе всегда одна и всегда должна находиться в ОП. А вот содержимое этой таблицы постоянно обновляется ОС и самим МП. Например, отправив сегмент из ОП на диск ОС должна соответствующим образом пометить дескриптор этого сегмента. Для того чтобы можно было изменять содержимое GDT должен быть создан дескриптор, где эта таблица была бы описана как сегмент данных. Этот дескриптор располагаеют в самой GDT.
ТАБЛИЦА IDT. Это дескрипторная таблица прерываний. Хотя таблица называется дескрипторной в ней располагаются только шлюзы. Связано это с тем что прерывание может произойти когда мы находимся на любом уровне привилегий (может на 0-м, а может на 3-м). При этом, на каком бы уровне мы не находились, мы должны получить доступ к обработчику. Иначе говоря, обработчик любого прерывания должен быть доступен (через IDT! )с любого уровня привилегий. А это можно осуществить только через шлюз. В данной таблице могут располагаться шлюзы трех типов:
• шлюзы задач;
• шлюзы ловушки;
• шлюзы прерывания.
Таблица IDT, так же как и таблица прерываний МП 8086, задает 256-ть (или меньше) обработчиков прерываний. Для каждого имеющегося в системе обработчика в таблице должен быть шлюз. Учитывая что шлюз занимает в памяти 8-мь байт можно сделать вывод что максимальный размер IDT равен 256×8=2Кбайта. Напомним, что в реальном режиме и в МП 8086 размер таблицы векторов прерываний 1Кбайт.
Таблица IDT может располагаться в любом месте ОП (в отличие от МП 8086, где подобная таблица фиксируется в младшем килобайте ОП). Для того чтобы МП 486 знал где находится IDT и каков ее размер внутри МП имеется регистр idtr. Его формат аналогичен рассмотренному выше формату регистра gdtr. Кстати отсюда следует (смотри формат регистра) что мы можем задать размер IDT больше 2-х Кбайт (вплоть до 64Кбайт), но смысл будут иметь не более 2-х младших килобайт этой области, так как обработчиков не может быть больше 256-ти. Загрузка регистра idtr производится командой lidt m 40 / m 48. Для этой команды справедливо все сказанное выше о команде lgdt.
Таблица IDT в системе всегда одна и всегда должна находиться в ОП. А вот содержимое этой таблицы по ходу работы может меняться. Для того чтобы можно было менять содержимое IDT для нее должен быть создан дескриптор, в котором эта таблица описана как сегмент данных. Этот дескриптор размещается в GDT.
ТАБЛИЦЫ LDT. Для каждой задачи в системе может быть создана ( а может и не создаваться) своя таблица LDT. В нее сводятся дескрипторы всех сегментов с которыми работает только эта задача. В LDT могут находится дескрипторы сегментов кода, данных и стека, а так же шлюзы вызова и задач.
Таким образом подобных таблиц в системе может быть много и располагаться они могут как в ОП, так и на диске. Для того чтобы МП знал где находится LDT текущей задачи в его состав введен специальный регистр ldtr. Формат этого регистра не похож на формат gdtr, а скорее похож на формат обычного сегментного регистра (см. рис. 49). Дело в том что смена LDT происходит при смене задачи, при этом МП загружает в ldtr новый селектор, задающий дескриптор LDT в таблице GDT. То есть «с точки зрения GDT» таблица LDT представляет из себя сегмент специального вида. У этого сегмента есть дескриптор, который располагается в GDT и в котором задан начальный адрес LDT, ее размер и. т. д.
15 0
63 0
селектор LDT
дескриптор LDT
видимая часть
теневая часть
Рис. 49
В видимую часть загружается селектор, адресующий дескриптор LDT в таблице GDT. При правильном обращении, из этого дескриптора берутся начальный адрес и размер LDT и копируются в теневую часть ldtr, с тем чтоб в дальнейшем эта информация была у МП «под рукой». В процессе работы системы загрузка нового селектора в видимую часть ldtr (а следовательно и смена LDT) происходит при переходе на новую задачу. Новый селектор берется при этом из соответствующего поля сегмента TSS входящей задачи. Для первоначальной загрузки регистра ldtr применяется команда lldt r 16 / m 16. Эта команда загружает в ldtr новый селектор из любого 16-ти разрядного регистра МП или из памяти. Эта команда доступна только в защищенном режиме и только на 0-м уровне привилегий.
Содержимое таблиц LDT может меняться по ходу работы. Для того чтобы у нас была возможность вносить изменения в LDT для каждой из них должен быть создан альтернативный дескриптор, где эти таблицы описаны как сегменты данных. Такие дескрипторы располагаются в GDT.
СЕГМЕНТЫ TSS. Сегмент TSS (сегмент состояния задачи) создается для каждой задачи в системе. Размер TSS должен быть не менее 104-х байт (67h). В этот сегмент в определенном порядке загружается содержимое почти всех внутренних регистров процессора. Эта информация называется «текущим состоянием задачи» или «контекстом задачи». При переключении на новую (входящую) задачу МП автоматически копирует содержимое своих регистров в TSS выходящей задачи и загружает в эти регистры информацию из TSS входящей задачи. Тем самым и происходит переключение на новую задачу. При этом МП конечно должен знать где в ОП находятся сегменты TSS и входящей и выходящей задач. Переключиться на новую задачу можно только обратившись к дескриптору TSS задачи (такие дескрипторы располагаются в GDT). Это можно сделать обратившись к такому дескриптору либо напрямую, либо косвенным образом через шлюз задачи (и в том и в другом случае это можно сделать командами jmp far, call far, retf и iret ). Так как в дескрипторе TSS располагается начальный адрес этого сегмента, процессору известно где в памяти находится TSS входящей задачи. Для того чтобы МП знал где в ОП находится TSS текущей задачи (при переключении задач текущая задача становится выходящей) внутри МП стоит регистр tr (регистр задачи). Формат этого регистра аналогичен формату регистра ldtr, рассмотренному выше. В видимой части регистра tr располагается селектор, адресующий дескриптор сегмента TSS в таблице GDT, а в теневой части - копия этого дескриптора (начальный адрес этого TSS в ОП и его размер). Таким образом адрес TSS выходящей задачи МП тоже известен.
Содержимое регистра tr в процессе работы меняется при смене задач, когда в видимую часть этого регистра загружается новый селектор. Для начальной загрузки этого регистра используется команда ltr r 16 / m 16. Эта команда аналогична рассмотренной выше команде lldt.
Сегменты TSS очень сильно привилегированны, с ними может работать только сам МП. В тоже время часто возникает необходимость внести изменения во внутреннее содержимое сегмента TSS (например, при задании исходного контекста задачи). Поэтому для любого TSS создается альтернативный дескриптор, где этот сегмент описан как обычный сегмент данных.
Более подробно механизм переключения задач и формат TSS будет рассмотрен в дальнейшем.
3.5..Механизмы адресации в защищенном режиме.
В защищенном режиме существуют три различных механизма формирования физического адреса:
• сегментный механизм;
• страничный механизм;
• механизм виртуального 86-го процессора (в дальнейшем V86 ).
Механизм V86 представляет из себя специфическую форму сегментного механизма. В любой момент времени в защищенном режиме работает либо сегментный механизм, либо механизм V86. Страничный механизм (в отличие от сегментного) мы можем включать и отключать. Страничный механизм не может работать сам по себе, так как исходной информацией для него является адрес, вырабатываемый сегментным механизмом ( или механизмом V86). То есть страничный механизм всегда работает после сегментного. Далее рассмотрим подробно работу всех этих механизмов, но прежде отметим что в МП 286 страничный механизм и механизм V86 не реализованы.
3.6 Сегментный механизм
Вначале рассмотрим еще раз (более подробно) формат сегментного регистра (рис. 50).
15 3
2
1 0
63 0
селектор
TI
RPL
копия дескриптора
видимая часть
теневая часть
Рис. 50
Тринадцать старших разрядов видимой части занимает селектор, адресующий дескриптор в одной из двух дескрипторных таблиц. В какой именно таблице находится этот дескриптор определяет бит TI. Если он равен 0 адресуется GDT, при TI=1 адресуется LDT. В теневой части МП хранит копию этого дескриптора.
Поле RPL задает «запрашиваемый уровень привилегий». Существуют три структуры, связанные с понятием уровня привилегий:
• DPL. Это два бита в дескрипторе, задающие уровень привилегий сегмента;
• CPL. Это два младших бита видимой части сегментного регистра cs, то есть это текущий уровень привилегий, на котором выполняется текущая программа (задача);
• RPL. Это два младших бита слова (селектора), загружаемого в видимую часть любого сегментного регистра при смене сегмента.
При смене сегмента данных МП проверяет права доступа к новому сегменту, реализуя проверку неравенства:
DPL >= max { CPL, RPL }.
Если это условие не выполняется доступ к новому сегменту данных предоставлен не будет, а будет прерывание. При смене сегмента кода проводится более жесткая проверка:
DPL = max { CPL, RPL }.
Из всего сказанного выше можно сделать следующие выводы. Мы можем перейти к новому сегменту данных, уровень привилегий которого равен нашему CPL или ниже его (по смыслу ниже, а по величине больше!) путем непосредственного обращения к дескриптору этого сегмента. Перейти же к более привилегированному (чем текущий CPL) сегменту данных не удастся, поскольку шлюзов для сегментов данных не существует. Для сегментов кода ситуация иная. Мы можем перейти к сегменту кода с таким же уровне привилегий (совпадающим с нашим CPL) обратившись к его дескриптору или перейти к более привилегированному сегменту кода через шлюз. Но мы не можем перейти к менее привилегированному сегменту кода, даже если он помечен как согласованный. Кроме того существует правило, согласно которому текущий DPL стека должен равняться CPL. То есть уровень привилегий стека должен быть таким же как уровень привилегий текущей программы ( сегменты данных могут быть менее привилегированными). За соблюдением этого правила следит сам МП, автоматически меняя стек при изменении уровня CPL на более высокий. Как он это делает будет показано в дальнейшем.
Поле RPL иногда используется для понижения текущего уровня привилегий. Если мы хотим, чтобы RPL ни на что не влияло, надо брать RPL = 0. Например, RPL может использоваться в следующей ситуации. Пусть у нас имеется привилегированная подпрограмма (нулевого уровня), к которой мы можем обратиться с пользовательского (третьего) уровня через известный нам шлюз. Пусть эта подпрограмма записывает информацию в заказанную нами область памяти. Параметром, передаваемым в эту подпрограмму, является селектор дескриптора сегмента данных, в который мы запрашиваем запись. Поскольку этот селектор формируем мы сами перед обращением к подпрограмме, у нас может возникнуть соблазн «обмануть» систему. Для этого мы записываем в этот селектор RPL = 0 и «просим» подпрограмму записать информацию в какой-нибудь системный сегмент (сегмент данных нулевого уровня). Если не предпринимать никаких мер, эта попытка будет успешной , так как подпрограмма имеет CPL = 0 и наше RPL = 0. Процессор отследить такие ситуации не может, они для него слишком сложные. Однако эту ситуацию может отследить сама подпрограмма. Для этого, получив селектор, она определяет CPL задачи, которая ее вызвала. Сделать это ей нетрудно, поскольку в ее стеке лежит адрес возврата в исходную программу. Определив, что вызов был с третьего уровня, подпрограмма меняет RPL в переданном ей селекторе с нуля на тройку, понижая тем самым собственный уровень привилегий. В результате мы не сможем обратится к заказанному сегменту данных, если его уровень привилегий выше трех.
Далее рассмотрим работу сегментного механизма при обращении в текущем сегменте, допустим на примере выполнения команды mov [bx+2] ,al .
• МП вычисляет Аэф. Для нашей команды Аэф = (bx)+2.
• МП проверяет не выводит ли полученный Аэф за заданные границы сегмента. Размер сегмента МП ( для рассматриваемой команды) возьмет из теневой части сегментного регистра ds.
• МП проверяет соответствие выполняемой команды заданным атрибутам сегмента. Атрибуты он также возьмет из теневой части ds. Для рассматриваемой команды будет произведена проверка «разрешен ли сегмент для записи».
• Если обе проверки прошли успешно МП формирует физический адрес по формуле Аф = начальный адрес сегмента + Аэф. Начальный адрес сегмента он также возьмет из теневой части ds.
• Если какая-то из проверок была неудачной МП генерирует соответствующее прерывание.
Рассмотрим далее работу сегментного механизма при смене сегмента. Чтобы перейти к новому сегменту (сменить сегмент) надо загрузить новый селектор в видимую часть соответствующего сегментного регистра. Для регистра cs здесь можно использовать команды jmp far, call far и другие, а для остальных сегментных регистров - mov sr , r 16 ; pop sr и ряд других.
МП берет загружаемый селектор и по биту TI определяет на какую дескрипторную таблицу он ссылается. Затем МП проверяет не выводит ли этот селектор за заданные (в gdtr или ldtr) размеры таблицы. Если не выводит, МП обращается в таблицу и находит там адресуемый дескриптор. Производится ряд проверок (в частности проверяются права доступа) и, если все они прошли удачно, в теневую часть сегментного регистра ( в который команда загружает селектор !) копируется найденный дескриптор, а в видимую часть этого регистра из команды загружается селектор.
Рассмотрим примерную последовательность действий МП при выполнении команды pop ds. Эта команда выталкивает из стека в видимую часть ds новый селектор и следовательно должна (если все проверки пройдут успешно) привести к смене сегмента данных. Однако сначала МП еще должен найти в стеке этот селектор. Поэтому вначале выполнения этой команды идет обращение в текущем сегменте стека.
• МП вычисляет Аэф = (sp).
• Проверяет не выводит ли этот адрес за заданные границы стека. Размер стека он берет из теневой части ss.
• Если проверка прошла удачно МП берет из теневой части ss начальный адрес сегмента стека и формирует Аф = начальный адрес + Аэф. По этому адресу из ОП считывается слово, представляющее из себя (по смыслу команды) новый селектор. Только с этого момента действительно начинается смена сегмента.
• По биту TI определяется дескрипторная таблица.
• Проверяется не выводит ли селектор за заданные размеры таблицы.
• В таблице отыскивается адресуемый дескриптор.
• Проверяется находится ли сегмент в ОП (по информации в дескрипторе).
• Проверяются права доступа.
• Проверяется отмечен ли адресуемый дескриптор как дескриптор сегмента данных (поскольку в команде указан ds !) или как сегмент кода, разрешенный для чтения.
• Если все проверки прошли успешно в теневую часть ds загружается копия найденного дескриптора и далее мы работаем с новым сегментом данных.
Далее приведем требования к сегментам, загружаемым в различные сегментные регистры процессора:
• В cs можно загружать только дескрипторы сегментов кода. Отметим здесь, что запись в кодовый сегмент всегда запрещена.
• В ds, es, fs и gs можно загружать дескрипторы сегментов данных и дескрипторы сегментов кода, но последние должны обязательно быть разрешены для чтения (что это за сегмент данных из которого нельзя даже прочитать информацию).
• Наиболее жесткими являются требования для регистра ss. В этот регистр можно загружать только дескрипторы сегментов данных, обязательно разрешенные для записи, у которых dpl = cpl и биты G и D в дескрипторе ( смотри формат дескриптора ) равны между собой.
При любом нарушении вышеперечисленных условий будет прерывание.
Сегментный механизм в защищенном режиме выключить нельзя, но его можно подавить. Для этого надо обеспечить загрузку в теневые части всех сегментных регистров дескрипторов, описывающих один и тот же сегмент. Обычно берется сегмент с начальным адресом 00000000h, имеющий размер 4 Гбайта и уровень привилегий 0 или 3. После этого содержимое сегментных регистров не меняется. Таким образом мы все время работаем в одном сегменте, в котором у нас располагаются и программа, и стек и данные. К тому же, так как начальный адрес этого сегмента равен нулю, адрес, поставленный программистом в команде будет сразу физическим адресом и при этом адресуемый объем памяти равен 4 Гбайта ! Это, очевидно, весьма удобно. Такая безсегментная память называется линейной (или плоской – flat) памятью. Однако такой способ организации памяти имеет и существенные недостатки: теряются механизм защиты и многозадачность. Страничный механизм при такой организации использовать можно. При этом появляется механизм защиты на уровне страниц. В минимальном случае при организации линейной памяти достаточно иметь GDT, содержащую два дескриптора (один кода, а другой данных).
3.7 Страничный механизм
Этот механизм, в отличие от сегментного мы можем включать и выключать по своему желанию. Правда эта задача относится к прерогативе системного программиста, а не пользователя. Для того чтобы включить страничный механизм достаточно установить в единицу бит PG в регистре cr0. Это старший (31-й) бит этого регистра. Сделать это можно только командой mov cr0 , r 32 . Команда lmsw r 16 / m 16 здесь не годится, так как она загружает только младшую половину cr0. При попытке включить страничный механизм в реальном режиме будет прерывание.
К серьезным недостатком сегментного механизма относится трудность организации подкачки сегментов с диска, поскольку сегменты имеют разные размеры и могут быть очень большими по объему. В отличие от сегментов страницы имеют фиксированный размер 4 Кбайта и располагаются в строго определенных местах ОП. Нулевая страница располагается в адресах 00000000h - 00000fffh, первая - в адресах 00001000h - 00001fffh и. т. д. Пересекаться страницы не могут. Отметим, что в Pentium используются страницы размером 4 Кбайта и 4 Мбайта, а в Р6 – 4 Кбайта, 4 Мбайта и 2 Мбайта. В дальнейшем будем называть страницы объемом 4 Кбайта обычными, а 4 Мбайта и 2 Мбайта – большими. В данном разделе речь пойдет только об обычных страницах.
Двенадцать младших разрядов начального адреса любой обычной страницы всегда равны нулю. Поэтому любой объект в памяти, имеющий подобный начальный адрес, называется выровненным по границе страницы.
Нетрудно видеть что всего в ОП может быть создано 220 страниц (4 Гбайта делить на 4 Кбайта). Все страницы объединяются в блоки. В один блок может входить до 210 страниц, при этом совсем необязательно подряд идущих. Иначе говоря в блок могут входить 100-я страница, 5-я страница, 346-я страница и. т. д. Для каждого блока создается так называемая таблица страниц. Каждый элемент этой таблицы описывает одну из входящих в блок страниц. Элемент таблицы страниц занимает в памяти 4 байта и называется элементом PTE (page table entry). Элемент PTE содержит начальный адрес (вернее 20 старших разрядов этого адреса, поскольку 12 младших все равно равны нулю) и атрибуты страницы, которую это элемент описывает. Нетрудно видеть что одна таблица страниц занимает в памяти ровно одну страницу ( 210 × 4 байта = 4 Кбайта). Соответственно любая таблица страниц выровнена по границе страницы, то есть 12 младших разрядов ее начального адреса равны нулю. Так же легко видеть что блоков, а следовательно и таблиц страниц может быть создано до 210.
Для всех таблиц страниц в памяти создается каталог таблиц. Он также занимает в памяти ровно одну страницу и выровнен по ее границе. Элементы каталога (они называются PDE (page directory entry)) аналогичны элементам PTE, только описывают они не страницы, а таблицы страниц. Начальный адрес ( вернее его 20 старших разрядов) каталога задаются МП в регистре cr3. При включенном страничном механизме каталог всегда должен находиться в ОП, а таблицы и страницы могут находиться как в памяти, так и на диске. Если идет обращение к странице (или таблице), которая находится на диске происходит прерывание. Обработчик этого прерывания должен подкачать страницу с диска после чего производится рестарт команды.
При включенном страничном механизме адрес, вырабатываемый сегментным механизмом (раньше мы его все время называли физическим), еще не является физическим адресом. Этот адрес принято называть линейным ( Ал). Линейный адрес условно разбивается на три части (поля). Поле DIR задает смещение в каталоге, поле PAGE - смещение в таблице, а поле OFFSET - смещение в самой странице. Далее на трех рисунках (рис 51-53) приводится графическая интерпретация работы страничного механизма с соответствующими пояснениями.
Рис. 51
Итак вначале у нас работает сегментный механизм, который формирует линейный адрес Ал. Затем начинает работать страничный механизм. МП берет из регистра CR3 20 старших разрядов начального адреса каталога, «пристыковывает» к ним 10-ть разрядов из поля DIR линейного адреса и в младшие разряды добавляет два нуля (рис. 51). Тем самым МП формирует адрес элемента PDE. Элемент PDE занимает в памяти 4 байта и всегда выровнен по границе двойного слова, именно поэтому два младших разряда его адреса берутся равными нулю. Из найденного в памяти элемента PDE процессор извлекает начальный адрес таблицы страниц (вернее 20 старших разрядов этого адреса) и переходит к следующему этапу (рисю 52).
Рис 52
Собственно этот этап очень похож на предыдущий. К 20 старшим разрядам начального адреса страницы, взятым из PDE, МП «пристыковывает» 10 разрядное смещение из поля PAGE линейного адреса Ал и в младшие разряды дописывает два нуля. Таким образом МП формирует адрес элемента PTE, из которого он извлекает начальный адрес страницы ( вернее опять таки 20 старших разрядов этого адреса). Затем МП переходит к последнему этапу формирования физического адреса (рис. 53).
На этом этапе к 20 старшим разрядам начального адреса страницы, взятым из PTE, «пристыковывается» 12 разрядное внутристраничное смещение из поля OFFSET линейного адреса Ал. В результате получается «долгожданный!» физический адрес Аф.
Как видно страничный механизм весьма громоздкий и требует только для формирования физического адреса двух обращений в память. Если это механизм будет всегда работать ожидать от МП высокого быстродействия не приходится. Поэтому для повышения быстродействия в состав МП введена кэш-память страниц (буфер TLB (translation lookaside buffer – «буфер предыстории трансляции»)). В этом буфере хранятся начальные адреса 32-х страниц, к которым были последние обращения процессора. После того как сегментный механизм выработал Ал, МП прежде всего ищет начальный адрес нужной страницы в буфере TLB и только если его там не окажется (а это бывает крайне редко так как процент кэш-попаданий в буфер составляет 95%) включается рассмотренный выше страничный механизм. Работа буфера TLB будет рассмотрена далее.
Страничный механизм предоставляет программисту (системному) следующие возможности:
• дает возможность упростить алгоритмы подкачки информации с диска, поскольку обмен информацией с диском ведется страницами, имеющими одинаковый небольшой размер;
• устраняет возможность возникновения фрагментации памяти ( при обмене с диском разноразмерными сегментами в памяти неизбежно возникают «дыры»);
• позволяет «транслировать» вырабатываемые процессором линейные адреса в другие области ОП. Когда программист пишет команду, адресующую ОП он задает в этой команде адрес. Сегментный механизм преобразует этот адрес в Ал, а страничный механизм преобразует Ал в Аф. При этом как правило Аф совсем «не похож» на Ал. Поэтому и говорят что процессор транслирует Ал в другое место ОП. Например, пусть сегментный механизм выработал Ал = 00000008h, а в элементе PTE, к которому мы обратимся по ходу работы страничного механизма (кстати из Ал видно что этот PTE будет 0-м элементом соответствующей таблицы страниц) в поле «начальный адрес страницы» задано 777ffh. Тогда Аф будет равен 777ff008h. Не трудно создать страницу для которой линейные адреса будут совпадать с физическими, для этого надо записать соответствующую информацию в соответствующие элементы PDE и PTE. Такие страницы называются страницами с прямым отображением в память. Возможность трансляции адресов является важным свойством страничного механизма и широко используется на практике. Приведем наиболее простой пример. Если какую-то страницу мы из ОП сбросили на диск, а потом вернули обратно в память эта страница скорее всего окажется совсем в другом месте ОП. Ничего страшного, достаточно изменить информацию в соответствующем PTE и вырабатываемые при обращении к этой странице адреса будут транслироваться в новое место ОП.
Рис. 53
3.8. Формат элемента PTE (PDE).
Формат элемента PTE (PDE) приведен на рис. 54.
31 12
11 9
8
7
6
5
4
3
2
1
начальный адрес
AVL
G
PS
D
A
PCD
PWT
U/S
R/W
P
Рис. 54
Для обычных страниц поле «начальный адрес» в PTE задает начальный адрес страницы, а такое же поле в PDE – начальный адрес таблицы страниц. Для больших страниц начальный адрес страницы задается в PDE, а таблицы страниц и соответственно PTE для таких страниц отсутствуют.
AVL (available - «свободный») - три бита системного программиста. МП с этими битами не работает и их может использовать по своему усмотрению системный программист. Обычно в этих битах накапливают некоторую статистику (число обращений к данной странице и.т.д.). В дальнейшем эту статистику можно использовать при решении вопроса о том, какую страницу лучше сбросить на диск.
G (global) –глобальная страница. Бит появился в Р6. Если страница отмечена как глобальная, при очистке буфера TLB начальный адрес такой страницы из буфера не удаляется. Так как очистка TLB обычно происходит при смене задач, получается что глобальная страница как бы передается из задачи в задачу. Для обычных страниц бит G определен в PTE, а для больших – в PDE. Процессор обращает внимание на бит G только если бит PGE в регистре cr4 установлен в единицу.
PS (page size) – размер страницы. Для любых страниц этот бит определен в PDE. При PS = 0 это обычная страница, при PS = 1 – большая страница. Бит PS появился в Pentium. Процессор обращает на него внимание если один из битов PSE или PAE в регистре cr4 установлен в единицу.
D (dirty)- «грязный бит». МП автоматически устанавливает этот бит в единицу если в данную страницу была запись. Сбрасывать этот бит МП не умеет и если это нужно сделать это задача системного программиста. Бит D проверяют когда страница сбрасывается на диск. При этом если в страницу не было записи ее не надо физически переписывать на диск ( она там уже есть, причем точно такая же), а достаточно отметить ее как отсутствующую в ОП. Если же запись в страницу была ее надо переписать на диск физически. Для больших страниц бит D определен в PDE, для обычных - в PTE.
A (accessed)- бит обращения. Этот бит также устанавливает сам МП (сбрасывает системный программист) если к странице было обращение. Этот бит можно привлекать при решении вопроса о том, какую страницу лучше отправить на диск.
Биты PCD (page-level cache disable) и PWT (page- level write through) задают стратегию кэширования данной страницы (таблицы). Если PCD = 1 - страница запрещена к кэшированию. При PWT =0 используется так называемая «обратная запись», а при PWT = 1 - «сквозная запись». Что это такое будет объяснено позже. Эти биты появились в МП 486.
U/S (user/supervisor)- «пользователь/супервизор». Если U/S =1 с данной страницей можно работать на любом уровне привилегий, в том числе и на 3-м (пользовательском). При U/S = 0 страница доступна только с уровней 0,1 и 2 (уровни ОС).
R/W (read/write)- «чтение/запись». Если R/W =1 для страницы разрешены и чтение и запись. Если R/W = 0 - запись в страницу запрещена. Бит R/W имеет смысл только на уровне пользователя. На уровнях ОС страница всегда доступна для записи (это не совсем точно, начиная с МП 486 имеется возможность запретить ОС запись в страницу). Таким образом биты U/S и R/W совместно организуют защиту на уровне страниц.
P (present)- бит присутствия. Если Р = 1 страница присутствует в ОП, при Р = 0 -отсутствует (находится на диске). В последнем случае вся остальная информация в PTE не имеет приведенного выше смысла. Обычно если Р = 0 в остальные разряды РТЕ системный программист записывает информацию о том где на диске искать эту страницу. Процессор этот бит только проверяет. Изменять значение этого бита – прерогатива ОС.
3.9. Особенности страничного механизма в Pentium и Р6.
В Pentium реализовано два варианта страничного механизма.
1. При PSE = 0 все страницы в системе 4 Кбайтные и механизм работы с ними ничем не отличается от рассмотренного выше.
2. При PSE = 1 одновременно могут использоваться 4Кбайтные и 4Мбайтные страницы.
Обращение к 4Мбайтным страницам пояснено на рис. 55. Как видно из этого рисунка, содержимое регистра cr3 задает (как и ранее) начальный адрес каталога, поле DIR адресует элемент PDE в каталоге. Если в этом элементе PDE бит PS = 1, из PDE берется начальный адрес страницы, а поле OFFSET задает смещение в этой странице.
В Р6 реализовано три варианта страничного механизма:
1. PAE = PSE = 0 – только 4Кбайтные страницы.
2. PAE = 0, PSE = 1 – и 4Кбайтные, и 4Мбайтные одновременно
3. PAE = 1, PSE = безразлично – и 4Кбайтные, и 2Мбайтные одновременно.
Первые два варианта ничем не отличаются от рассмотренных выше. Далее рассмотрим третий вариант.
Бит PAE – «расширение физического адреса». Если этот бит установлен в единицу, к процессору добавляются четыре адресные линии А35-32 и он начинает адресовать 64 Гбайта оперативной памяти. При этом сегментный механизм продолжает вырабатывать 32 разрядный адрес, то есть реально процессор адресует все те же 4 Гбайта ОП. Однако страничный механизм дает возможность транслировать эти 4 Гбайта в любое место 64 Гбайтного пространства.
Поскольку формат физического адреса увеличивается до 36 бит, четырех байт, отводимых под элементы PTE и PDE, оказывается недостаточно, поэтому эти элементы становятся восьмибайтными (см. рис. 56 ). Так как размер каталога и таблиц страниц при этом не меняется (остается равным 4Кбайта), количество элементов (соответственно, PDE и PTE) в каждой из этих структур уменьшается в два раза. Иначе говоря получается, что процессор может адресовать только 218 страниц. Для того чтобы он мог адресовать, как и положено, 220 страниц в систему вводится не один, а четыре каталога. Для их адресации вводится еще одна структура, называемая таблицей указателей на каталог , включающая в себя четыре восьмибайтных указателя DPE (directory pointer entry). Формат DPE представлен на рис 57. Регистр cr3 теперь задает начальный адрес таблицы указателей, при этом этот адрес занимает разряды 31-5 данного регистра. Отсюда можно сделать вывод, что таблица указателей на каталог всегда занимает в памяти 32 байта (четыре элемента по восемь байт каждый) и всегда должна быть выровнена по 32-х байтной границе (пять младших разрядов начального адреса таблицы указателей равны нулю.
Рис. 55
63 36
35 12
11 9
8
7
6
5
4
3
2
1
резерв
н. адрес
AVL
G
PS
D
A
PCD
PWT
U/S
R/W
P
Рис. 56
63 36
35 12
11 9
8 5
4
3
2 1
резерв
н. адр. катал.
AVL
резерв
PCD
PWT
резеров
1
Рис. 57
Рисунки 58 и 59 поясняют работу страничного механизма при РАЕ = 1, соответственно, для 4Кбайтных и 2Мбайтных страниц. Как видно из рисунков разряды 31-30 линейного адреса теперь задают один из четырех элементов DPE в таблице указателей на каталог.
Рис. 58
Рис. 59
Работа с 4 Кб и 2 Мб страницами требует, как видно из рис. 58 и рис. 59, трехуровневой структуры таблиц и расширения форматов PTE и PDE до 8 байтов. Эти отличия от исходного алгоритма работы страничного механизма на практике приводят к трудностям в реализации операционных систем.
Для того чтобы исключить этот недостаток и в то же время сохранить возможность адресации 64 Гб памяти начиная со старших моделей Р6 введен еще один вариант страничного механизма, который фирма назвала PSE-36. Этот вариант позволяяет использовать 36 разрядную адресную шину и адресовать 64 Гб памяти. В то же время, в этом варианте используется двухуровневая структура таблиц, а элементы этих таблиц имеют формат 4 байта.
Для того чтобы установить, поддерживает ли данный процессор механизм PSE-36, надо выполнить команду cpuid при eax=1. Если после выполнения этой команды в бите 17 регистра edx вернулась единица значит рассматриваемый механизм поддерживается. Подробней смотри раздел 3.29.
Необходимо отметить, что механизм PSE-36 отменяет вариант, когда 4 Кб и 4 Мб страницы адресуют 4 Гб памяти (вариант 2 для Р6, смотри выше в этом же разделе), вернее этот вариант просто вырождается в частный случай PSE-36.
В механизме PSE-36 используются 4 Кб и 4 Мб страницы, при этом 4 Кб страницы позволяют обратиться только к 4 Гб адресному пространству, а страницы 4 Мб – к 64 Гб адресному пространству. В таблице 9 приведены варианты страничной трансляции для процессоров, поддерживающих PSE-36.
Таблица 9
бит
PG (cr0)
бит
PAE (cr4)
бит
PSE (cr4)
бит
PS (PDE)
размер страницы
Шина адреса
*
*
*
нет
32 бита (страничный механизм выключен)
1
*
4 Кб
32 бита
1
1
4 Кб
32 бита
1
1
1
4 Мб
36 бит
1
1
*
4 Кб
36 бит
1
1
*
1
2 Мб
36 бит
Вариант PSE-36 выделен в таблице 9 жирной строкой. Далее рассмотрим этот вариант. Для адресации 64 Гб памяти адрес должен быть 36 разрядным. Двадцать два младших разряда начального адреса любой 4 Мб страницы всегда равны нулю. Следовательно, в поле начального адреса страницы в элементе PDE (при PS=1) должны быть записаны 14 старших разрядов этого адреса. В то же время это поле начального адреса имеет формат 20 бит (биты 31-12), так как именно столько разрядов необходимо для задания адреса 4 Кб страницы. Таким образом, для 4 Мб страниц биты 21-12 поля начального адреса являются резервными. Именно этот факт и использован в PSE-36, поскольку появляется возможность (за счет резервных бит) не увеличивать формат элемента PDE, что в свою очередь определяет двухуровневую структуру таблиц. Старшие разряды адреса (А35-32) располагаются в резервных битаах 16-13 поля начального адресаа. То есть для 4 Мб страниц есть два формата поля начального адреса в PDE:
1. PSE-36 не поддеррживается. Разряяды 31-22 – начальный адрес (А31-22), разряды 21-12 – резерв.
2. PSE-36 поддерживается. Разряды 31-22 – адрес (А31-22), разряды 21—17 – резерв, разряды 16-13 – адрес (А35-32) и бит 12 используется для специальных целей, связанных со стратегией кэширования (можно считать его резервным).
Таким образом, за исключением использования бит 16-13 PDE, работа механизмаPSE-36 совпадает с работой механизма, показанного на ррис. 55. Эти механизмы будут полностью идентичны если при использовании PSE-36 в биты 16-13 PDE записать нули. Страницы 4Кб невозможно использовать аналогичным образом поскольку у них нет в поле начального адреса резервных битов и, следовательно негде располагать разряды А35-32.
3.10 Механизм V86.
Пусть нам надо выполнить на 32 разрядном МП программу, написанную для МП 8086 . Конечно это можно сделать в реальном режиме. Но на практике это оказывается крайне неудобным. Представьте себе что вам надо покидать Windows при запуске любого DOS - приложения. Кроме того в реальном режиме теряются такие преимущества защищенного режима как многозадачность и защита сегментов. Все это привело к тому что начиная с МП 386 был введен механизм V86, как бы эмулирующий в защищенном режиме работу МП 8086.
МП, работая в режиме V86, формирует физический адрес точно таким же способом, что и МП 8086. То есть берется содержимое сегментного регистра (вернее его видимой части ), умножается на 16-ть, к полученному числу прибавляется Аэф в результате получается Аф. (это не совсем так, здесь используется несколько иная схема с тем же конечным результатом). При смене содержимого сегментного регистра ни к каким дескрипторным таблицам МП не обращается, а просто загружает в видимую часть сегментного регистра новое число, которое задает начальный адрес нового сегмента. В то же время режим V86 представляет из себя подмножество защищенного режима и позволяет использовать многозадачность, защиту сегментов и даже включать страничный механизм.
МП переходит в режим V86 если установить в единицу флаг VM в регистре флагов (ef). Однако сделать это совсем непросто, поскольку ни одна команда на состояние этого флага не влияет. Существует всего два способа переключения в режим V86 (из обычного защищенного режима) и всего один способ выхода из этого режима в обычный защищенный режим.
Первый способ входа предполагает смену задачи. Когда из TSS входящей задачи в регистры МП загружается новая информация она загружается и в регистр флагов. Если при этом в новом образе ef бит VM будет установлен, новая задача будет выполняться в режиме V86. Напомним что для переключения на новую задачу надо обратиться к ее сегменту TSS (напрямую или через шлюз) в дескрипторной таблице GDT. Это можно сделать командами jmp far или call far.
Выйти из режима V86 в обычный защищенный режим таким способом невозможно. Как уже говорилось выше в режиме V86 МП не обращается в дескрипторные таблицы, следовательно мы не можем обратиться к TSS и сменить задачу. Единственный способ выхода из режима V86 заключается в следующем. При любом прерывании МП, как и в любом другом режиме, автоматически сохраняет содержимое регистра в стеке, а затем сбрасывает флаг VM. Таким образом после любого прерывания мы автоматически оказываемся в обычном защищенном режиме. Отметим здесь также что хотя МП в режиме V86 работает также как и МП 8086 в качестве таблицы прерывания он использует таблицу IDT !
Кстати из вышесказанного вытекает второй способ входа в режим V86. Команда iret (возврат из прерывания) автоматически восстанавливает из стека содержимое регистра флагов, в том числе и флаг VM, при этом если VM становится равен единице мы попадаем в режим V86. Здесь надо отметить что такой возврат в режим V86 возможен только если команда iret выполняется на нулевом уровне привилегий.
Итак можно сделать следующие выводы. В режиме V86 МП формирует физический адрес по схеме МП 8086. Единственным серьезным отличием от МП 8086 является использование таблицы прерываний IDT (имеется еще ряд очень мелких отличий, но здесь они не рассматриваются). Так же как МП 8086 32 разрядный МП в режиме V86 адресует младший мегабайт ОП, однако если использовать страничный механизм этот мегабайт можно транслировать в любое место ОП. Более того используя многозадачность можно запустить сразу несколько задач V86 выделив каждой свой мегабайт памяти и переключаться между этими задачами.
Обычно для обслуживания режимаV86 в системе создается специальная программа, называемая «монитор V86». Как правило монитор является частью обработчика прерывания типа 13 –«общая защита» (#GP). Важным является тот факт, что в режиме V86 текущий уровень привилегий задачи (CPL) всегда равен 3!
3.11 Методы обработки прерываний, возникших в режиме V86.
По терминологии фирмы Intel все прерывания делятся на:
• Немаскируемые аппаратные прерывания (NMI);
• Маскируемые аппаратные прерывания (hardware interrupt);
• Исключения (особые случаи) (exception);
• Программные прерывания (команды int n) (software interrupt).
Используемый метод зависит от желания системного программиста, от возможностей процессора и от установки некоторых флагов и полей. Рассмотрим эти флаги и поля.
Поле IOPL (input-output privilege level) – это биты 12 и 13 регистра флагов ef. Когда процессор выполняет команду, которая является ЧУВСТВИТЕЛЬНОЙ к уровню привилегий он проверяет условие: текущий уровень привилегий задачи (CPL) должен быть не ниже IOPL:
CPL <= IOPL.
Если это условие не выполняется, возникает исключение #GP. Важно помнить, что в режиме V86 CPL всегда равен 3 !!
В защищенном режиме к чувствительным командам относятся команды ввода/вывода (in; out; ins; outs) и команды, влияющие на состояние флага разрешения прерывания if ( cli; sti.). В режиме V86 к чувствительным относятся только команды: cli; sti; pushf; popf; int n и iret.
Флаг VME (0-й бит регистра cr4) (virtual mode extension – расширенный V86). Этот флаг появился в Pentium.
Флаги VIF и VIP (соответственно, биты 19 и 20 в регистре флагов ef). Процессор, находясь в V86, работает с этими флагами только при VME=1. VIF – virtual interrupt flag (виртуальное разрешение прерываний). VIP – virtual interrupt pending (виртуальный флаг отложенного прерывания). Наличие этих флагов позволяет легче контролировать работу программ 86-го процессора, выполняющихся в V86 и меняющих состояние флага IF. То есть если IOPL<3, программе не позволят менять IF, но, если доступен VIF, позволят поменять VIF и при этом не будет #GP. Более подробно работа с этими флагами описана ниже.
БИТОВАЯ КАРТА ПЕРЕНАПРАВЛЕНИЯ ПРОГРАММНЫХ ПРЕРЫВАНИЙ ( Redirection bitmap). Используется только при VME=1. Смысл здесь в следующем. Когда процессор находится в режиме V86 все прерывания (в том числе и программные по командам int n ) переводят его в защищенный режим. Чаще всего, когда обработчик защищенного режима определяет что прерывание вызвано командой int n, возникшей в V86 он возвращает это прерывание в V86 для его обработки стандартными средствами DOS и BIOS. На этих переключениях между режимами теряется время, поэтому, начиная с Pentium, была введена возможность (если VME=1) сразу оставлять прерывания по некоторым командам int n для обработки в V86. Какие при этом команды сразу перенаправляются в V86, а какие идут в защищенный режим определяют соответствующие биты битовой каты перенаправления. Каждый бит этой карты соответствует своему типу прерывания (n). Если бит = 1, int n выводит в защищенный режим, если бит = 0, int n обрабатывается в V86. То есть всего в этой карте 256 бит (32 байта). Располагается карта в TSS текущей задачи непосредственно перед битовой картой ввода/вывода ( см. раздел 3.13). Таким образом, бит для int 0 имеет адрес:
База битовой карты ввода /вывода минус 32 байта.
Соответственно бит для int 255 имеет адрес:
База битовой карты ввода /вывода минус 1 бит.
Теперь перейдем непосредственно к методам обработки прерываний, возникающих в режиме V86. Все прерывания при этом удобно разбить на три пересекающихся класса ( то есть одно и то же прерывание может входить сразу в несколько классов). Разбиение на классы приведено в таблице 10.
Таблица 10.
Класс 1
NMI
Маскируемые аппаратные внешние прерывания
Особые случаи
Программные прерывания
Класс 2
Нет
Маскируемые аппаратные внешние прерывания
Нет
Нет
Класс 3
Нет
Нет
Нет
Программные прерывания
Существует три основных способа обработки КЛАССА 1.
Первый способ заключается в следующей последовательности действий:
1. Произошло прерывание в режиме V86.
2. Процессор устанавливает TF=0, VM=0 и, если переход к обработчику происходит через шлюз прерываний, IF=0.
3. Процессор переходит к обработчику защищенного режима. Поскольку при этом уровень привилегий меняется ( с 3 на 0) процессор автоматически меняет стек на более привилегированный (уровня 0).
4. Процессор автоматически запоминает в новом стеке содержимое видимых частей сегментных регистров gs,fs, ds,es.
5. Процессор очищает эти регистры (сбрасывает в ноль).
6. Процессор запоминает в новом стеке ss:esp, ef, cs:eip и код ошибки, если конечно этот код есть..
7. (Далее начинается работа системного программиста). Обработчик проверяет флаг VM (не в регистре ef, а в образе этого регистра, лежащем в стеке!) и определяет что прерывание произошло в V86. Далее как раз и существуют три пути.
Первый путь . Обработать все в обработчике защищенного режима (в этом обработчике мы как раз сейчас и находимся) и, выполнив iret, вернутся в V86. При этом iret проверит VM (в образе ef в стеке) и восстановит все регистры надлежащим образом.
Второй путь. Обработчик в котором мы находимся вызывает командой call монитор V86 (обычно это специальная программа, тесно связанная с обработчиком #GP.). Последний обрабатывает прерывание и возвращает (по ret) прерывание обработчику. Обработчик выполняет iret и.т.д.
Третий путь связан с программными прерываниями, обработка которых имеет специфику и будет рассмотрена ниже.
КЛАСС 2. К этому классу относятся маскируемые внешние аппаратные прерывания (hardware interrupt) при VME=1 ( то есть разрешены VIF и VIP) и IOPL<3. Напомним о сути проблемы. Так как в V86 CPL=3 (a IOPL<3) попытка выполнения команды, изменяющей значение флага IF, приведет к #GP. Действительно, программе можно разрешить менять этот флаг только в однозадачной системе. В многозадачной же системе запрет внешних прерываний какой-либо задачей может привести к монопольному захвату системы со стороны этой задачи. Но, с другой стороны, многие задачи, написанные для 8086 и реального режима работают с этим флагом. Если VME=1 выполнение команды cli или sti, несмотря на IOPL<3, не приводит к #GP, хотя IF при этом не изменяется, но зато изменяется VIF. Итак пусть у нас IF=1, а VIF=0 и произошло аппаратное прерывание. Оно будет воспринято (так как IF=1). Далее осуществляется та же последовательность действий, что и для Класса 1 (см. пункты 1-7 для Класса 1).
8 Обработчик (он же знает что это аппаратное прерывание, он ведь и есть обработчик этого аппаратного прерывания) проверяет флаг VIF ( в образе, взятом из стека), если этот флаг равен единице, далее все идет обычным образом (как в Классе 1), если же этот флаг равен нулю, обработка прерывания не производится! В последнем случае обработчик просто устанавливает в хранящемся в стеке образе ef флаг VIP=1 (имеется отложенное прерывание) и по iret уходит назад в V86.
Когда задача V86 установит флаг VIF (командой sti) процессор проверит флаг VIP. Если при этом он окажется в единице произойдет #GP и отложенное прерывание можно будет обработать по Классу 1 с единственной отличительной чертой: перед возвратом в V86 надо установить VIP=0 (в образе ef в стеке).
КЛАСС 3. К этому классу относятся программные прерывания (по int n). Вообще программные прерывания могут также относится к Классу1. В зависимости от значений флагов и полей можно выделить шесть методов обработки программных прерываний (см. таблицу 11).
Таблица 11.
Метод
VME
IOPL
Бит в карте перенаправления
1
3
безразлично
2
<3
безразлично
3
1
<3
1
4
1
3
1
5
1
3
6
1
<3
МЕТОД 1. Программное прерывание обрабатывается в рамках Класса 1. Смотри Класс 1.
METOД 2. Выполнение int n приводит к #GP. Далее смотри пункты 1-7 для Класса 1. Обработчик #GP, определив что прерывание пришло из V86, передает управление монитору V86 ,который по сути есть часть обработчика #GP. Монитор либо сам обрабатывает прерывание, либо, что чаще, передает его обратно в V86 для обработки средствами DOS и BIOS . Для этого монитор предпринимает следующие шаги:
• Находит в таблице прерываний V86 (не в IDT!!) вектор «местного» обработчика и по нему определяет начальный адрес этого обработчика.
• Переписывает f, cs и eip, пришедшие из V86, из своего стека 0-го уровня в стек V86 ( 3-го уровня)
• Подменяет в своем стеке 0-го уровня адрес возврата на найденный адрес обработчика V86.
• Выполняет iret и мы в обработчике V86.
• Когда обработчик V86 выполнит команду возврата iret произойдет #GP (так как IOPL<3) и мы вновь окажемся в мониторе.
• Монитор восстановит адрес возврата
• Перепишет f из стека 3 в стек 0 (эта операция связана с тем, что многие DOS-обработчики возвращают результат в регистре флагов).
• Выполнит iret для возврата в V86.
МЕТОД 3. Полностью идентичен Методу 2.
МЕТОД 4. Идентичен Методу 1.
МЕТОД 5. Резко отличается от всего изложенного выше. Здесь нет перехода в защищенный режим, так как прерывание перенаправляется в V86 (остается и обрабатывается в V86 как в 8086). Действия процессора при этом тоже отличаются:
• Процессор сохраняет в стеке (уровня 3) f с NT=0 и IOPL=0
• Процессор сохраняет в стеке cs и ip
• Процессор устанавливает в f флаги TF=0 и IF=0.
• Процессор берет вектор из таблицы V86 (не IDT) и переходит на обработчик. Далее стандарт для 8086.
Метод 5 совпадает с обработкой прерываний в Реальном Режиме.
МЕТОД 6. Незначительно отличается от Метода 5 действиями процессора:
• Сохраняет f с IOPL=3 и IF=VIF
• Сохраняет cs и ip
• Устанавливает VIF=TF=0
• Переходит на обработчик.
При возврате по команде iret из методов 5 и 6 процессор понимает, что он в режиме V86 по VM=1. Сами методы 5 и 6 он при этом не различает, но возврат получается правильным, поскольку флаги VIF, VIP, IOPL, VM при этом возврате не модифицируются.
3.12 Механизм переключения задач. Формат сегмента TSS
Как уже говорилось ранее размер сегмента TSS должен быть не менее 104-х байт. При обращении к дескриптору TSS МП проверяет записанный в этом дескрипторе размер и если он оказывается меньше 104-х байт генерируется прерывание. Однако сегмент TSS может иметь больший размер. В этой дополнительной области сегмента TSS может, например, располагаться битовая карта ввода-вывода - input-output map (смотри ниже). Кроме того эту дополнительную область может использовать в своих целях системный программист. Например, в этой области системный программист может сохранять содержимое регистров арифметического сопроцессора. Переключая задачи МП, для экономии времени, не сохраняет контекст сопроцессора. Отсюда если задача А переключилась на задачу В и обе они работают с сопроцессором, очевидно что задача В (если не принять мер) испортит контекст задачи А. Поэтому переключаясь на новую задачу МП автоматически устанавливает бит TS (задача переключена) в регистре CR0. При выполнении любой команды сопроцессора МП проверяет бит TS и если он установлен будет прерывание. Обработчик этого прерывания должен сохранить контекст сопроцессора, сбросить бит TS и обеспечить рестарт команды.
Далее рассмотрим формат сегмента TSS (смотри рис. 60):
Дадим необходимые пояснения к рисунку. Формат рисунка - 4 байта по горизонтали. Слева от полей приведено смещение (0h, 4h и.т.д) относительно начала сегмента TSS. Назначение таких полей как EIP - EDI и ES -GS по нашему мнению очевидно и мы их рассматривать не будем. Остальные поля либо неочевидны, либо имеют свою специфику.
Поле «обратной связи» (previous task link). Пусть задача А вызвала задачу В в качестве подпрограммы (командой call far). Естественно предполагать что когда-нибудь нам потребуется возврат в задачу А. Для того чтобы куда-нибудь вернуться нам потребуется адрес возврата. Адресом возврата здесь будет селектор дескриптора сегмента TSS задачи А. Однако задачи А и В ничем между собой не связаны и в общем случае задаче В этот селектор неизвестен. Поэтому когда задача А вызывает задачу В командой call far МП автоматически загружает в поле обратной связи задачи В (входящей задачи) селектор дескриптора TSS задачи А. Этот селектор МП берет из видимой части регистра tr. Тем самым обеспечивается возможность возврата в задачу А. Если переключение задач идет по команде jmp far, поле обратной связи входящей задачи заполняется нулями, так как возврат куда-либо не предполагается.
31 16
15 0
0h
поле обратной связи
4h
esp0
8h
ss0
0ch
esp1
10h
ss1
14h
esp2
18h
ss2
1ch
cr3
20h
eip
24h
ef
28h
eax
2ch
ecx
30h
edx
34h
ebx
38h
esp
3ch
ebp
40h
esi
44h
edi
48h
es
4ch
cs
50h
ss
54h
ds
58h
fs
5ch
gs
60h
ldtr
64h
база битовой карты ввода-вывода
T
Рис. 60
CR3. Наличие этого поля показывает что при переключении задач меняется содержимое регистра cr3, а следовательно происходит переход к новому каталогу таблиц (если конечно страничный механизм включен).
LDTR. Из поля LDTR TSS входящей задачи загружается видимая часть регистра ldtr. Таким образом происходит переключение на новую таблицу LDT. Старое содержимое видимой части регистра ldtr в поле LDTR TSS выходящей задачи не сохраняется (для экономии времени), поскольку подразумевается что задача всегда работает с одной и той же LDT.
Бит Т (trap – «ловушка»). Если в TSS задачи В этот бит установлен в единицу, то при переключении на задачу В будет прерывание типа 1. Этот бит используется для отладки.
SSi - ESPi. Каждая пара такого вида задает вершину стека для одного из уровней привилегий. Всего в TSS задаются три таких пары для уровней привилегий 2, 1 и 0. А для 3-го уровня привилегий вершина стека в TSS не задается ! Содержимое этих полей при переключении задач не меняется. Вообще эти поля используются не в процессе переключения задач, а в процессе выполнения задач. Как уже говорилось ранее, существует правило, согласно которому, уровень привилегий текущего сегмента стека (DPL стека) должен быть всегда равен CPL. Пусть мы работаем на уровне привилегий i (CPL = i ). И пусть затем через шлюз вызова мы вызвали подпрограмму с более высоким уровнем привилегий (теперь CPL< i ). В соответствии с рассмотренным правилом мы обязаны сменить стек (на более привилегированный). Как раз в этом случае МП и возьмет вершину стека соответствующего уровня из TSS текущей задачи. При этом он автоматически сохранит вершину старого стека в новом стеке, чтобы ее можно было восстановить при возврате из подпрограммы. Поскольку мы никаким способом не можем перейти к менее привилегированной программе то на 3-й уровень мы можем попасть только с 3-го уровня. Именно поэтому в TSS отсутствуют поля SS3:ESP3.
Поле битовой карты ввода-вывода задает смещение этой карты (если она есть) относительно начала TSS.
Процессор может работать с сегментами TSS микропроцессора i 286. Формат такого сегмента отличается от рассмотренного выше хотя бы потому что регистры МП 286 16-ти разрядные. TSS МП 286 содержит следующую последовательность полей ( полей, заполненных нулями в нем нет и по объему он меньше TSS, рассмотренного выше): поле обратной связи, sp0, ss0, sp1, ss1, sp2, ss2, ip, f, ax, ..., ds, ldtr.
3.13 Битовая карта ввода вывода
В регистре флагов ( ef ) имеется двух битовое поле IOPL, задающее уровень привилегий, на котором задаче разрешены операции ввода/вывода. Например, если CPL = 3, а в поле IOPL задана 2-ка при попытке выполнить команду in ( out или аналогичные) будет прерывание. Связано это с тем, что операции ввода/вывода - «опасные» операции, они могут вывести систему из строя. Поэтому система принимает меры защиты. Скорее всего наша команда in все же будет выполнена, но не напрямую. Обработчик прерывания запросит ОС и она, если это допустимо, выполнит нашу команду гарантированно корректно. Сменить содержимое поля IOPL можно только находясь на 0-м уровне привилегий.
Такое ограничение на операции ввода/вывода зачастую оказывается излишне жестким. Например имеет смысл ограничить доступ пользователя к 0-му каналу таймера (порт 40h), на работе которого базируется служба системного времени. Однако нет никакого смысла ограничивать доступ ко 2-му каналу таймера (порт 42h), заведующему генерацией звука. Для решения этой проблемы в TSS может быть создана битовая карта ввода/вывода.
Карта содержит в себе столько бит, сколько в системе портов. Каждый бит карты соответствует одному восьмиразрядному порту. Максимально в карте может быть 64Кбит. Если в i-ом бите записан 0, то доступ к i-му порту разрешен всегда (IOPL игнорируется), если же там записана 1, доступ к порту будет предоставлен только если не нарушаются права, заданные полем IOPL.
Процессор может работать не только с восьмиразрядными но и 16-ти и 32-х разрядными портами. 16-ти разрядному порту в карте ставятся в соответствие два смежных бита, начинающихся с четного номера. Аналогично 32-х разрядному порту соответствуют четыре смежных бита, начинающихся с номера, кратного 4-м. Приведем пример (рис. 61):
Из приведенного примера карты видно, что в системе всегда доступны 8-ми разрядные порты с адресами 1h, 2h, 3h, 4h и 6h, а также один 16-ти разрядный порт с адресом 2h. Остальные порты защищены полем IOPL.
Рис. 61
В режиме V86 условие CPL <= IOPL при выполнении команд in и out не проверяется и доступ к портам определяется битом в битовой картой ввода-вывода, то есть последняя для задач V86 создается обязательно. Кроме того в TSS задачи V86 непосредственно перед битовой картой ввода-вывода может располагаться битовая карта перенаправления прерываний.
3.14 Действия процессора при переключении задач.
Введем вначале понятие занятой задачи. Задача называется занятой если она в данный момент выполняется. Кроме того если одна задача вызвала другую задачу в качестве подпрограммы обе задачи будут занятыми. При обращении к занятой задаче генерируется прерывание. То есть задача не может переключиться сама на себя. В дескрипторе TSS в четырехбитном поле TYPE есть бит В (формат поля TYPE для дескриптора TSS - x x B x). Если этот бит установлен в единицу задача является занятой. С этим битом работает сам МП. Он этот бит и устанавливает и сбрасывает.
Для того чтобы переключиться на новую задачу, надо обратиться к дескриптору TSS этой задачи. Это можно сделать следующими четырьмя способами.
1. Команда jmp far или call far адресует дескриптор TSS в таблице GDT. В любой из этих команд присутствует селектор и смещение (например, jmp 0010:00222222h – здесь 0010 – селектор, 00222222 – смещение). Если при этом селектор адресует дескриптор TSS, смещение, заданное в команде игнорируется.
2. Те же команды адресуют шлюз задачи. Селектор, заданный в команде, адресует при этом шлюз задачи в GDT или LDT, а смещение, как и ранее, игнорируется. Селектор дескриптора TSS берется из шлюза.
3. Прерывание через шлюз задачи. В принципе подобен второму варианту.
4. Переключение задачи происходит при выполнении команды iret, если флаг NT (флаг вложенной задачи) в регистре флагов ef установлен в единицу (это возврат из вложенной задачи). Селектор дескриптора TSS входящей задачи при этом берется из поля обратной связи TSS текущей (выходящей) задачи.
Далее приводится (несколько упрощенно) примерная последовательность действий процессора при переключении задач.
1. По известному селектору (взятому из команды, или из шлюза или из поля обратной связи) процессор находит дескриптор TSS в таблице GDT.
2. Процессор производит ряд проверок:
• проверяет права доступа;
• проверяет размер TSS;
• проверяет входящую задачу на занятость, при этом входящая задача должна быть занята, если переключение инициировано командой iret и свободна во всех остальных случаях.
• проверяет присутствуют ли структуры, необходимые при переключении задач (TSS входящей и TSS выходящей задач), в ОП.
3. Если переключение инициировано командой call или прерыванием, в поле обратной связи записывается селектор дескриптора TSS выходящей задачи (адрес возврата), который процессор берет из видимой части регистра tr.
4. В TSS выходящей задачи процессор копирует содержимое своих внутренних регистров.
5. Выходящая задача помечается как свободная если переключение инициировано командой jmp или iret, если же переключение инициировано командой call или прерыванием, выходящая задача остается занятой. До этого момента любое прерывание воспринимается в контексте выходящей задачи, начиная со следующего пункта прерывания воспринимаются уже в контексте новой задачи.
6. Из TSS входящей задачи в регистры процессора загружается новая информация (контекст входящей задачи).
7. Входящая задача помечается занятой.
8. Если переключение инициировано командой call или прерыванием, флаг NT в регистре флагов устанавливается в единицу.
9. Бит TS (задача переключена) в регистре cr0 устанавливается в единицу. Напомним, что этот бит связан с математическим сопроцессором (см. раздел 3.12).
3.15 Формат дескриптора.
Все создаваемые в системе дескрипторы можно разделить на системные и не системные. К системным относятся шлюзы, дескрипторы TSS и дескрипторы LDT. К не системным относятся дескрипторы сегментов кода, данных и стеков. Как системные, так и не системные дескрипторы занимают в памяти 8-мь байт и имеют примерно одинаковый формат (см. рис. 62).
Поле BASE задает 32-х разрядный начальный адрес сегмента.
Поле LIMIT задает размер сегмента. Этот размер может измеряться в байтах или страницах. Если размер сегмента задается в байтах размер сегмента может меняться от 1 байта до 1 Мбайта. Если размер задается в страницах он может меняться от 4 Кбайт до 4 Гбайт (от одной страницы до 220 страниц). Если размер сегмента стека задается в байтах, то этот размер лежит в более ограниченных пределах: от 1 байта до 64 Кбайт. Размеры сегментов TSS и таблиц LDT задаются только в байтах.
В каких единицах измеряется размер сегмента задает бит гранулярности G (granularity). Если G = 0 размер измеряется в байтах, при G = 1 -в страницах.
7 0
0h
Limit 7-0
1h
Limit 15-8
2h
Base 7-0
3h
Base 15-8
4h
Base 23-16
5h
P
DPL
S
TYPE
6h
G
D
U
Limit 19-16
7h
Base 31-24
Рис. 62
Бит P (present)- бит «присутствия». Если Р = 1 сегмент присутствует в ОП, а при Р = 0 - отсутствует, то есть находится на диске. При Р = 0 поля BASE и LIMIT не имеют вышеописанного смысла.
Бит U (user)- бит «пользователя». МП с этим битом не работает и системный программист может его использовать для набора статистических сведений о сегментах.
Бит D (default operation size)- бит «размерности». Это более сложный для описания бит. Возьмем для примера три команды: mov al , bl ; mov ax , bx и mov eax , ebx. Первая из этих трех команд имеет код операции ( КОП ) 88h, а вот у двух последующих команд КОП одинаковый, он равен 89h. То есть по коду операции возможно отличить «восьмиразрядные» команды от «не восьмиразрядных», а вот «шестнадцатиразрядные» команды от «тридцатидвухразрядных» по КОП отличить невозможно ( разумеется речь здесь идет об «аналогичных» командах). Для того чтобы МП мог отличить эти команды друг от друга перед одной из них транслятор поставит «префикс размера операнда» (66h). Перед какой из двух этих команд транслятор поставит префикс зависит от того как пользователь описал свою программу. У него для этого есть ассемблерные директивы use16 и use32. А вот МП проинтерпретирует эти команды в зависимости от бита D, который он возьмет в теневой части регистра cs. При D = 0 МП интерпретирует код 89h как команду mov ax , bx, а код 66h 89h - как команду mov eax, ebx. При D = 1 интерпретация таких кодов будет прямо противоположной. Кроме префикса размера операнда есть еще «префикс размера адреса» (67h). Его тоже ставит транслятор, например перед одной из двух команд: mov al ,[bx+2] и mov al , [ebx+2]. Интерпретация таких команд процессором аналогичным образом зависит от значения бита D в регистре cs. Отметим что перед командой могут стоять оба префикса одновременно. Эта несколько запутанная ситуация с префиксами и битом D связана с желанием уменьшить расход памяти и повысить быстродействие МП. Если было бы однозначно задано что префиксы, допустим, ставятся перед всеми «тридцатидвухразрядными» командами, а все «шестнадцатиразрядные» команды идут без префиксов казалось было бы проще. Однако если большинство команд программы «тридцатидвухразрядные», такая программа будет в этом случае (за счет префиксов !) занимать значительно больше памяти и медленнее выполняться. Вот бит D и предоставляет нам возможность как бы сообщать МП каких команд в нашей программе будет меньше 16-ти или 32-х разрядных. Перед теми которых меньше и будут стоять префиксы. Как уже говорилось в основном для интерпретации префиксов привлекается бит D из регистра cs. Биты D в регистрах ds, es, fs и gs по-видимому ни на что не влияют. Бит D в регистре ss определяет размер указателя стека ( D = 0 - sp, D = 1 - esp). В дескрипторах, копируемых в сегментный регистр стека ss биты D и G должны быть согласованы (равны между собой), кроме того бит D в подобных дескрипторах принято называть битом В (big – «бит большого сегмента»). Отметим также, что в дескрипторах «системных» сегментов биты D и G смысла не имеют.
Бит S (system)- бит «системного сегмента». При S = 0 дескриптор описывает системный сегмент. В зависимости от значения бита S процессор интерпретирует поле TYPE. При S = 1 (не системный сегмент) поле TYPE может иметь один из двух форматов.
Первый формат приведен на рис. 63
1
C
R
A
Рис. 63
Здесь 1 в старшем разряде поля TYPE означает что это сегмент кода. Бит А (accessed)-бит обращения. МП устанавливает этот бит при обращении к сегменту. Сбрасывать этот бит процессор сам не умеет, это делает системный программист. Бит R (read enable)- бит разрешения считывания. При R = 0 запрещается считывание информации из этого сегмента ( программу можно выполнять, но нельзя копировать). И наконец бит C (conforming)- бит «согласованного» сегмента. Понятие согласованного сегмента кода было введено раньше ( см. раздел 3.2).
Второй формат поля TYPE при S = 1 приведен на рис. 64.
E
W
A
Рис. 64
Здесь 0 в старшем разряде говорит о том что это сегмент данных. Бит A - бит обращения, такой же как и для сегментов кода. Бит W (write enable)- бит разрешения записи. При W = 0 сегмент запрещен для записи. Бит Е (expansion direction – «направление расширения») – грубо говоря, позволяет различать сегменты данных и сегменты стека (Е = 0 - это сегмент данных). Вернее, бит Е влияет на то как МП интерпретирует поле LIMIT. Продемонстрируем это с помощью рис. 65.
Рис. 65
Как видно из рисунка при Е = 0 МП считает что сегмент располагается в границах base - base+limit и следовательно если Аэф>base+limit мы выходим за заданные границы сегмента. При Е = 1 сегмент для МП располагается в границах base+limit - 64K (4Г) и выход за границы сегмента будет при Аэф 0, значит есть BRAND ID им и пользуемся для определения процессора.
• Если bl = 0, используем сигнатуру процессора.
Этот алгоритм пригоден, если мы уверены в том, что наша программа не будет запускаться на процессорах ниже Pentium. Если это не так, перед тем как запускать CPUID придется стандартным образом поработать с регистром флагов.
В заключение в таблице 25 приводятся коротко все описанные выше сведения о команде CPUID.
Таблица 25
Функция в ЕАХ
Информация о процессоре
Базовая информация
ЕАХ Максимальное значение функции для базового набора
ЕВХ Genu
ЕСХ ntel
EDX ineI
1
ЕАХ Сигнатура процессора или, если установлен бит 18 в особенностях, старшие разряды сериального номера.
ЕВХ Brand ID, chunks, APIC ID
ЕСХ Резерв
EDX Особенности процессора
2
ЕАХ, ЕВХ, ЕСХ, EDX Дескрипторы кэшей
3
ЕАХ, ЕВХ Резерв
ЕСХ Биты 31-0 сериального номера
EDX Биты 63-32 сериального номера
Расширенная информация
80000000h
ЕАХ Максимальное значение функции для расширенного набора
ЕВХ, ЕСХ, EDX Резерв
80000001h
ЕАХ Расширение сигнатуры и битов особенностей (пока зарезервир.)
ЕВХ, ЕСХ, EDX Резерв
80000002h
ЕАХ Маркерная строка
ЕВХ ЕСХ, EDX Продолжение маркерной строки
80000003h
ЕАХ, ЕВХ, ЕСХ, EDX Продолжение маркерной строки
80000004h
ЕАХ, ЕВХ, ЕСХ, EDX Продолжение маркерной строки
3.30 Краткие характеристики микропроцессорв фирмы Intel.
В таблице 26 приводятся характеристики основных микропроцессоров фирмы Intel. Данные, приведенные в таблице 26, даются на момент первого выпуска соответствующего микропроцессора.
Таблица 26
Тип
Дата выпуска
Частота
Транзисторов на кристалле
Формат регистров
Размер ШД
Адресует память
Кэши
8086
1978
8 MHz
29K
16 GP
16
1 M
нет
286
1982
12,5 MHz
134 K
16 GP
16
16 M
нет
386
1985
20 MHz
275 K
32 GP
32
4 G
нет
486
1989
25 MHz
1,2 M
32 GP
80 FPU
32
4G
L1:8 K
Pentium
1993
60 MHz
3,1 M
32 GP
80 FPU
64
4 G
L1: 16 K
Pentium Pro
1995
200 MHz
5,5 M
32 GP
80 FPU
64
64 G
L1: 16 K
L2: 512 K
Pentium II
1997
266 MHz
7 M
32 GP
80 FPU
64 MMX
64
64 G
L1: 32K
L2: 512 K
Pentium III
1999
500 MHz
8,2 M
32 GP
80 FPU
64 MMX
128 XMM
64
64 G
L1: 32K
L2: 512 K
Pentium III
со встроенным L2 кэшем
1999
700 MHz
28 М
32 GP
80 FPU
64 MMX
128 XMM
64
64 G
L1: 32 K
L2: 256 K
Pentium 4
2000
1,5 GHz
42 M
32 GP
80 FPU
64 MMX
128 XMM
64
64 G
L1: 8 K
Trace: 12 K
L2: 256 K
4. Микропроцессор Itanium
4.1 Введение.
Новый 64 разрядный микропроцессор фирмы Intel ITANIUM (Itanium II) представляет собой типичный RISC-процессор, имеющий большое число внутренних регистров, фиксированный формат машинной команды и ряд других особенностей, характеризующих процессоры данного вида.
Фиксированный формат машинной команды позволяет достаточно просто и эффективно организовать конвейер команд, за счет однотипности действий процессора при выполнении любой команды. Большое число регистров и особенности их использования позволяет свести до минимума количество обращений к оперативной памяти. И все это вместе взятое приводит к существенному увеличению быстродействия процессора.
Архитектурно Itanium совершенно не похож на 32 разрядные процессоры предыдущих поколений (имеются ввиду процессоры фирмы Intel). Но в то же время, Itanium полностью поддерживает программную модель и систему команд 32 разрядных процессоров (IA-32 архитектура). Иначе говоря, в любой конкретный момент времени процессор может выполнять либо базовый поток команд Itanium, либо поток команд IA-32. Для переключения с одного потока команд на другой используются специальные команды. Команда jmpe (это команда IA-32) переключает процессор на базовый поток команд, а команда br.ia (команда базового потока – «branch IA») – на поток IA-32. При выполнении потока IA-32 процессор конкретным образом ассоциирует часть своих внутренних регистров с регистрами процессора класса Pentium III (смотри раздел 4.5), тем самым, переходя на программную модель 32-разрядного процессора.
Операционную систему (ОС), предназначенную для Itanium, можно, в принципе, написать в одном из трех вариантов:
• поддерживает только поток команд IA-32;
• поддерживает только базовый поток команд;
• поддерживает микширование потоков.
Очевидно, что первый вариант выглядит несколько «несерьезным», так как возникает вопрос: «А зачем тогда разрабатывали Itanium?». Но, с другой стороны, это вариант означает, что принципиально нет никаких препятствий к тому, чтобы использовать на Itanium наши «любимые» ОС: Windows 95, 98, 2000,...XP…
Команды базового потока совсем не похожи на хорошо известный Ассемблер 16 и 32 разрядных процессоров. Например, привычный для нас фрагмент кода на обычном Ассемблере
cmp eax, ebx
jne m1
add ebx, 7
jmp m2
m1: add ebx,10
m2: ………
; сравнить содержимое регистров
; если не равно – прыжок на m1
; если равно – прибавить к ebx 7
; прыжок на m2
; если не равно – прибавить к ebx 10
в системе команд Itanium может выглядеть примерно так
cmp.ne р1,р2 = r1,r2
(р2) add r4 = r2, 7
(p1) add r4 = r2, 10
// сравнить содержимое регистров r1 и r2,
// по результатам сравнения установить
// значения предикатов р1 и р2 (р2=1, если
// r1= r2, а p1 – в противном случае)
// выполняется, если р2 = 1, результат в r4
// выполняется, если р1 = 1, результат в r4
Приведенные в данном разделе сведения о процессоре Itanium не претендуют на полноту и целостность. Скорее это попытка изложения некоторых основных архитектурно-программных концепций, заложенных в этот процессор.
Данный раздел предполагает, что читатель достаточно хорошо знаком с Intel-процессорами предыдущих поколений (IA-16 и IA-32 процессорами). То есть ему знакома программная модель этих процессоров и механизмы формирования физического адреса оперативной памяти (сегментный и страничный).
4.2 Программная модель пользователя.
Как и в других процессорах в Itanium можно выделить программную модель пользователя и программную модель системного программиста.
Регистры пользователя доступны на любом уровне привилегий, хотя для некоторых из них на любом уровне привилегий доступны только определенные поля, а не весь регистр в целом.
Системные регистры доступны только на 0 уровне привилегий.
Набор внутренних регистров Itanium очень велик, поэтому не представляется возможным отобразить их на одном рисунке. Таким образом, ограничимся их перечислением и кратким описанием. В данном разделе рассмотрим регистры, составляющие программную модель пользователя (Application Register Model).
Регистры общего назначения (General Registers). Таких регистров 128. На модели они обозначаются GR0 - GR127, а в ассемблерных командах r0 – r127. Формат этих регистров – 64 значащих бита, кроме того, с каждым таким регистром ассоциирован еще один добавочный бит, называемый NaT (Not a Thing – «Не вещь»). Этот бит используется для отслеживания отсроченных спекулятивных особых случаев.
Регистры общего назначения разбиты на два подмножества. Регистры GR0 – GR31 называются статическими. Они доступны любым программам и подпрограммам. При этом в регистре GR0 навсегда «зашит» 0. Это очень удобно, поскольку довольно часто приходится оперировать с нулем. Статические регистры GR16 – GR31 составляют, так называемый Регистровый Банк (Banked Registers). Собственно в процессоре два набора регистров GR16 – GR31. Один из этих наборов называется Банк0, другой - Банк1. В любой конкретный момент времени доступны регистры только одного банка, регистры другого банка в это время сохраняют свое состояние. Переключение с одного банка на другой происходит при прерывании, при возврате из прерывания по команде rfi (return from interruption) или по команде bsw (bank switch).
Регистры GR32 – GR127 составляют Регистровый Стек (Stacked Registers). Смысл его в максимальном уменьшении количества обращений к памяти при вызове подпрограмм и возврате из них. Программа (или подпрограмма) с помощью команды alloc выделяет в Регистровом Стеке «окно» (frame), в которое входят локальные и выходные регистры. При этом не важно, в какой области Стека будет физически выделено это окно. Для текущей программы окно всегда начинается с GR32. То есть, допустим, программа (подпрограмма) затребовала 8 регистров и ей выделили физически регистры GR40 – GR47. Процессор при этом автоматически установит указатель начала Стека на GR40 и этот регистр получит временное имя GR32. Все остальные регистры Стека также получат соответствующие временные имена: GR41 GR33 ……GR39 GR127. При вызове подпрограммы, процессор автоматически проворачивает Стек таким образом, что новой подпрограмме оказываются видны только выходные регистры родительской программы (подпрограммы), а локальные регистры родительской программы оказываются недоступны. Подпрограмма может запросить свое окно в Стеке и это окно будет включать выходные регистры родительской программы. При возврате из подпрограммы окно родительской программы автоматически восстанавливается. Таким образом, в подпрограмме не надо сохранять значения регистров родительской программы (локальные регистры) и легко организовать обмен параметрами между родительской программой и подпрограммой через выходные регистры. Регистровый Стек можно использовать и в качестве вращаемых регистров (см. ниже)
Предикаты (Predicate Registers)
Набор из 64 однобитных регистров PR0 – PR63, используемых для фиксации результата в командах сравнения. Все эти регистры доступны любым программам на любом уровне привилегий. Предикаты разбиты на два подмножества: статические предикаты (PR0 – PR15) и «вращаемые» предикаты (PR16 – PR63) (Rotation Predicate Registers). В PR0 навсегда «зашита» единица, что соответствует значению «истина». Вращаемые предикаты можно программным образом (с помощью команды alloc) переименовывать, назначая им временные номера. Используется вращение предикатов (и не только предикатов, но и других регистров) при ускоренном выполнении циклов, когда на исполнение, благодаря конвейеру, запускаются сразу несколько итераций цикла (modulo scheduling loops). При этом возникает необходимость для каждой итерации использовать наборы регистров, являющихся физически различными, но имеющими одинаковые временные имена, в том числе и регистры условий.
Регистры с плавающей точкой (Floating Point Registers)
Набор из 128 (82 разрядных) регистров FR0 – FR127. Регистры доступны на любом уровне привилегий. Набор разбит на два подмножества: статические регистры (FR0 – FR31) и вращаемые регистры (FR31 – FR127). В FR0 навсегда зашито 0.0, а в FR1 – 1.0. Назначение вращаемых регистров аналогично назначению вращаемых предикатов.
Регистры переходов (Branch Registers)
Восемь 64 разрядных регистра, в которые можно записать целевые адреса для косвенных переходов. Доступны на любом уровне привилегий.
Указатель команды (Instruction Pointer)
64 битный регистр (IP), в котором хранится адрес командной группы (bundle), в которой содержится выполняемая в данный момент команда. Процессор всегда считывает из памяти командную группу, содержащую три команды (по 41 бит на команду) и 5 битное поле шаблон. Последнее задает дополнительные сведения о выполнении входящих в данную группу команд. Поскольку группа всегда 16 байтная и всегда выровнена по соответствующей границе, младшие 4 бита IP всегда равны нулю. Содержимое IP можно прочитать с помощью команды mov ip.
Маркер текущего окна (Current Frame Marker)
38 битный регистр CFM. Задает текущее окно в Регистровом Стеке. Содержит размер окна, размер области локальных регистров и указатели на регистр общего назначения, регистр с плавающей точкой и предикат, переименованные, соответственно, в GR32, FR32 и PR16. При выполнении команды br.call (вызов подпрограммы) содержимое CFM автоматически копируется в поле Маркер Предыдущего Окна (Previous Frame Marker) в регистре Предыдущее Функциональное Состояние (Previous Function State Register), а в CFM записывается новая информация, описывающее новое окно без локальных и вращаемых регистров, но с выходными регистрами родительской программы. Первый выходной регистр родительской программы при этом переименовывается в GR32. При возврате из подпрограммы по команде br.ret родительское окно автоматически восстанавливается, поскольку информация из PFM переписывается в CFM. Прямая запись в CFM или прямое чтение CFM невозможны.
Маска Пользователя (User Mask)
Шестибитное поле в Processor Status Register (смотри раздел 4.5), доступное приложениям. Содержит пять флагов, определяющих способы контроля выравнивания, мониторинга производительности и др.
Регистры Данных Мониторинга Производительности (Performance Monitor Data Registers).
Эти регистры представляют собой счетчики аппаратных и программных событий, происходящих в системе. Любая модель Itanium содержит минимум 4 пары счетчиков производительности PCM/PMD. PCM (Performance monitor configuration registers) относятся к программной модели системного программиста и доступны только ОС. В PCM задается, какие события будет подсчитывать соответствующий PMD. Сами счетчики (PMD) могут быть доступны пользователю, если имеется соответствующее разрешение ОС.
Регистры идентификации процессора (Processor identifiers).
Обозначаются CPUID0 – CPUIDN, то есть для различных моделей число этих регистров различно. CPUID0 – CPUID4 существуют обязательно. Сколько всего регистров CPUID содержит данный процессор задается в соответствующем поле (биты 7 – 0) CPUID3. В CPUID0 – CPUID1 в ASCII коде задаются сведения о производителе. CPUID2 зарезервирован. В CPUID3 задается номера семейства и модели. В CPUID4 задаются особенности, которые поддерживает данный процессор.
Регистры приложений (Application registers)
Регистровый файл AR0 – AR127, содержащий самые разнообразные регистры специального назначения. В частности, в состав файла входят Регистры Ядра (KR0 – KR7), через которые ОС может поставлять приложению разнообразную информацию, Интервальный Таймер (ITC) и другие. Часть регистров в файле зарезервированы, а часть используется для IA-32 архитектуры.
4.3 Адресация памяти.
Для целостности картины проведем краткий экскурс в историю.
Первым широко известным процессором фирмы Intel был процессор i580. Механизм формирования физического адреса оперативной памяти (Аф) в этом процессоре был прост и понятен. Этот адрес просто брался из пары регистров или из команды. То есть программист, написав в команде адрес 0777h, мог быть уверен, что процессор обратится именно к ячейке памяти с адресом 0777h и ни к какой другой. Для программиста это было удобно, но при написании ОС это приводило к почти неразрешимым проблемам, поскольку такая абсолютная адресация в корне противоречит концепции загрузки программы в произвольное место оперативной памяти.
Для преодоления этого недостатка, начиная с 16 разрядного процессора i8086, был введен сегментный механизм формирования физического адреса оперативной памяти. Теперь адрес, задаваемый в регистре или команде, представлял собой не физический адрес памяти, а смещение в некоем сегменте относительно начального (базового) адреса этого сегмента. Начальные адреса всех используемых в данный момент сегментов задавались процессору в специальных сегментных регистрах. Поскольку загрузка информации в эти сегментные регистры возлагалась в основном на ОС, никаких особых проблем при перемещении программы в памяти не возникало: программа загружалась в первое свободное место памяти, а ОС соответствующим образом заполняла сегментные регистры. Сегментный механизм, претерпевая определенные модификации, просуществовал почти три десятилетия, вплоть до Pentium IV.
С появлением 32 разрядных процессоров и ОC Windows выяснилось, что и сегментный механизм, с точки зрения простоты реализации ОС, имеет существенные недостатки. При этом основная проблема была связана с реализацией концепции «виртуальной памяти». Последняя предполагает, что часть сегментов текущего процесса (задачи) находится в оперативной памяти, а другая часть – на жестком диске, подкачиваясь по мере необходимости. Именно реализация алгоритмов подкачки сегментов с диска и приводила к существенным трудностям, поскольку, в общем случае, сегменты являлись разноразмерными и могли быть очень большими (превышающими имеющийся объем оперативной памяти). Попытка устранения этого недостатка привела, начиная с процессора i386, к появлению страничного механизма формирования физического адреса оперативной памяти. При этом считается, что вся память разбита на страницы фиксированного (как правило, небольшого) размера и для формирования Аф надо знать начальный адрес (или номер) страницы и внутристраничнре смещение.
Страничный механизм в 32 разрядных процессорах фирмы Intel является надстройкой над сегментным механизмом. Процесс формирования физического адреса памяти можно при этом описать следующим образом:
• сначала работает сегментный механизм, который формирует так называемый линейный адрес, который является входным параметром для страничного механизма;
• страничный механизм, используя буфер TLB (translation lookaside buffer) или, если начального адреса нужной страницы в буфере нет, находящиеся в ОП таблицы страниц, транслирует полученный линейный адрес в физический.
Как следует из этого краткого экскурса, страничный механизм практически, в определенном смысле, дублирует сегментный механизм и, именно поэтому, в Itanium нет сегментного механизма, а оставлен только страничный, причем довольно серьезно модифицированный по сравнению с 32 разрядными процессорами.
Как правило, современные ОС поддерживают различные модели распределения адресного пространства. Без учета различных нюансов все эти модели можно разделить на два типа:
• Multiple Address Space (MAS) – Разделение адресного пространства между процессами. В такой модели каждому процессу выделяется уникальная область адресного пространства памяти, недоступная другим процессам.
• Single Address Space (SAS) – Единое адресное пространство. Здесь все процессы разделяют единое адресное пространство, а защита от влияния процессов друг на друга осуществляется на уровне доменов (например, страниц или групп страниц).
Механизм адресации процессора Itanium разработан с учетом аппаратной поддержки обеих типов моделей адресного пространства. Так, для поддержки MAS, используются Регистры Регионов, идентифицирующие Virtual Regions (виртуальные регионы) внутри адресного пространства. Для поддержки SAS используются механизмы защиты домена (Protection Domain mechanisms).
Формирование физического адреса памяти в Itanium происходит по следующей схеме. Из регистра общего назначения (GRi) берется 64 разрядный адрес, который называют виртуальным (Virtual Address). В соответствии с этим адресом определяется Регистр Региона, содержащий Идентификатор Региона. По идентификатору региона и нашему виртуальному адресу в TLB производится поиск соответствующей Записи (Запись содержит начальный адрес искомой страницы). В описании фирмы Intel Запись называют Translation Entry – «элемент трансляции». Предположим, что искомый элемент трансляции в TLB найден. Процессор производит ряд проверок (права доступа, соответствие атрибутам страницы и другие) и, если все они прошли успешно, к начальному адресу страницы, взятому из элемента трансляции, пристыковывается внутристраничное смещение, взятое из виртуального адреса. Это и будет искомый Аф.
Если нужная Запись в TLB отсутствует, процессор может (если соответствующий механизм включен) произвести поиск искомого элемента трансляции в Хэш-таблице (VHPT – Virtual Hash Page Table). Эта таблица создается в оперативной памяти операционной системой и ее местоположение процессору известно. Если нужный элемент трансляции в Хэш-таблице найден, процессор помещает его в TLB и так далее. Если же нужный элемент трансляции отсутствует и в Хэш-таблице, генерируется особый случай TLB Miss fault. Обработчик этого особого случая, являющийся частью ОС, может найти нужный элемент трансляции в таблицах страниц ОС и поместить его в TLB или в Хэш-таблицу. После этого происходит рестарт отказавшей команды. Этот процесс упрощенно показан на рис. 87.
Рис. 87
Адресуемая процессором оперативная память представляет собой виртуальный линейный массив объемом 264 байт. Этот массив разбивается на 8 регионов объемом 261 байт каждый. Каждому из регионов присваивается 24 битный Идентификатор Региона, который записывается в один из восьми Регистров Региона. Старшие три бита (63-61) виртуального адреса и осуществляют выбор Регистра Региона, из которого будет взят Идентификатор.
Используя последовательные Идентификаторы Регионов ОС может «сливать» соседние Регионы в одно целое, образуя Регионы большего объема (до 264 байт при слиянии всех восьми Регионов).
Адресное пространство Региона разбивается на страницы, размер которых для каждого конкретного Региона задает ОС (4Кб, 8Кб, 16Кб, 64Кб, 256Кб, 1Мб, 4Мб, 16Мб, 64Мб или 256 Мб).
Виртуальный Адрес, взятый из 64 разрядного регистра общего назначения, условно разбивается на три поля. Разряды 63-61 содержат Номер Виртуального Региона и, как уже отмечалось, задают Регистр Региона, из которого считывается Идентификатор Региона. Младшие биты (сколько конкретно – зависит от размера страницы) задают смещение в странице. Это смещение проходит через процесс трансляции без изменений. Оставшиеся биты содержат Номер Виртуальной Страницы. Процессор производит поиск нужной Записи в TLB, сравнивая соответствующие поля всех Записей с найденным Идентификатором Региона и Номером Виртуальной Страницы.
Если нужная Запись найдена, начинает работать Механизм Защиты Домена. Для работы этого механизма каждой Виртуальной Странице ставится в соответствие уникальный Ключ Защиты (Protection Key). При запуске нового процесса, ОС записывает все необходимые для данного процесса Ключи Защиты в специальный массив регистров (Protection Key Registers). Когда идет обращение к Виртуальной Странице и нужная Запись в TLB найдена, процессор достает из этой Записи прописанный в ней Ключ Защиты и сравнивает его с содержимым всех регистров массива. Если сравнения не произошло, возникает особый случай Key Miss fault. Если в каком-то регистре обнаружен совпадающий ключ защиты, процессор производит дополнительную проверку на «защиту от записи», «защиту от выполнения» и «защиту от чтения». Атрибуты для этой проверки процессор берет из регистра, в котором обнаружен Ключ. Если эта проверка оказывается неудачной, возникает особый случай Key Permission fault.
Если все проверки прошли успешно из Записи считывается Номер Физической Страницы (по сути это старшие разряды физического адреса страницы) и к нему пристыковывается смещение в странице, взятое из Виртуального Адреса.
В состав процессора входят два TLB: TLB команд (ITLB) и TLB данных (DTLB). Первый используется при выборке из памяти очередной команды (вернее, очередной командной группы), второй – при обращении к данным.
Каждый из этих TLB делится на два подмножества: Регистры Трансляции (Translation Registers) и Кэш Трансляции (Translation Cache). Граница этих подмножеств в общем случае плавающая, то есть ОС может сама задавать, сколько элементов TLB будут рассматриваться в качестве Регистров, сколько в качестве Кэша. Основная разница между Регистрами и Кэшем заключается в том, что Записи, хранящиеся в Регистрах меняются крайне редко, а в Кэше, если он заполнен, - при каждом кэш-промахе. То есть в Регистрах ОС «зашивает» Записи, относящиеся к «критическим» областям памяти (например, область ядра ОС), а в Кэше – Записи для «обычных» областей памяти.
4.4 Программная модель системного программиста.
Данная модель включает в себя все рассмотренные выше регистры пользователя, а также регистры, доступные только на нулевом уровне привилегий. К последним относятся:
Регистр статуса процессора (Processor Status Register – PSR)
64 разрядный регистр, содержащий управляющую информацию для выполняемого в данный момент процесса и задающий тем самым текущую конфигурацию системы. В частности, биты 33 – 31 этого регистра задают текущий уровень привилегий CPL. Изменить CPL можно только на нулевом уровне, то есть это прерогатива ОС.
Регистры управления (Control Registers)
Регистровый файл, состоящий из большого числа (порядка восьмидесяти) 64 разрядных регистров, в котором фиксируется состояние процессора при прерывании и специфицируются глобальные процессорные параметры для прерываний и управления памятью.
Регистры отладки (Debug Breakpoint Registers –DBR/IBR)
64 разрядные регистры, в которых задаются контрольные точки останова по командам (IBR) и по данным (DBR). Контрольная точка при этом представляет собой виртуальный или физический адрес некоторого диапазона памяти. В состав процессора входят не менее четырех пар таких регистров.
Регистры конфигурации мониторинга производительности (Performance Monitor Configuration Registers – PMC)
Рассматривались выше. Смотри раздел 4.2.
Регистры регионов (Region Registers – RR)
Введены для поддержки MAS модели памяти. Смотри раздел 4.3.
Регистры ключей защиты (Protection Key Registers - PKR)
Введены для поддержки SAS модели памяти. Смотри раздел 4.3.
Буфер TLB
Смотри раздел 4.3.
4.5 Поддержка архитектуры IA-32.
Как уже говорилось в разделе 4.1, Itanium поддерживает архитектурную модель процессора класса Pentium III. При этом, выполняя код IA-32 Itanium ассоциирует (картирует) часть своих внутренних регистров с регистрами 32 разрядных процессоров. Схема этого картирования приведена в табл. 27
Таблица 27
Itanium
IA-32
Примечание
GR8
EAX
разряды 31-0 GR
GR9
ECX
-//-
GR10
EDX
-//-
GR11
EBX
-//-
GR12
ESP
-//-
GR13
EBP
-//-
GR14
ESI
-//-
GR15
EDI
-//-
GR16
DS
разряды 15-0 GR; видимая часть DS
GR16
ES
разряды 31-16; видимая часть
GR16
FS
разряды 47-32; видимая часть
GR16
GS
разряды 63-48; видимая часть
GR17
CS
разряды 15-0; видимая часть
GR17
SS
разряды 31-16; видимая часть
GR17
LDTR
разряды 47-32; видимая часть
GR17
TR
разряды 63-48; видимая часть
GR24
ES
теневая часть ES
GR27
DS
-//-
GR28
FS
-//-
GR29
GS
-//-
GR30
LDTR
-//-
GR31
GDTR
IP
EIP
разряды 31-0 IP
AR24 (EFLAG)
EF
разряды 31-0 AR
AR25 (CSD)
CS
теневая часть CS
AR26 (SSD)
SS
-//-
AR27 (CFLG)
CR0/CR4
СОДЕРЖАНИЕ
1. ЭВМ ОБЩЕГО НАЗНАЧЕНИЯ 3
1.1 Структура ЭВМ общего назначения. 3
1.2 Арифметико-логические устройства. 4
1.3 Устройства управления. 4
1.4 RISC и CISC процессоры. 6
1.5 Форматы машинных команд. 7
1.6 Способы адресации. 8
1.7 Стековая адресация. Виды стеков. 8
2. МИКРОПРОЦЕССОРНЫЙ КОМПЛЕКТ К1810 8
2.1 Микропроцессор К1810ВМ86. 8
2.2 Назначение входов/выходов ВМ86 в минимальном режиме. 9
2.3 Назначение входов/выходов ВМ86 в максимальном режиме. 12
2.4 Внутренняя архитектура МП ВМ86. 13
2.5 Сегментация памяти. 13
2.6 Программная модель МП ВМ86. 14
2.7 Организация оперативной памяти. 17
2.8 Организация адресного пространства портов ВУ. 18
2.9 Методы обмена информацией между МП и портами ВУ. 19
2.10 Параллельный программируемый адаптер К1810ВВ55 (i8255). 20
2.11 Пример использования и программирования адаптера 22
2.12 Программируемый таймер К1810ВИ54 (i8254). 23
2.13 Пример использования таймера. 27
2.14 Обработка прерываний. 28
2.15 Система прерываний ВМ86. 30
2.16 Контроллер прерываний К1810ВН59 (i8259). 31
2.17 Дополнительная информация о настройке ВН59. 35
2.18 Прямой доступ к памяти. 37
2.19 Контроллер прямого доступа к памяти К1810ВТ37 (i8237). 37
2.20 Программирование КПДП ВТ37 39
2.21 Организация процессорного модуля ВМ86. 40
2.22. Организация шинного интерфейса в максимальном режиме 43
2.23. Слабо связанные конфигурации. 45
2.24. Арбитр шин К1810ВБ89 (i8289). 47
2.25 Сильно связанные конфигурации на примере совместной работы МП86 и арифметического сопроцессора ВМ87. 51
2.26. Формат машинной команды ВМ86. 52
3. 32-х РАЗРЯДНЫЕ ПРОЦЕССОРЫ ФИРМЫ INTEL. 54
3.1. Знакомство с терминологией 54
3.2. Реальный режим 58
3.3 Переключение в защищенный режим 59
3.4. Системные таблицы 62
3.5..Механизмы адресации в защищенном режиме. 64
3.6 Сегментный механизм 64
3.7 Страничный механизм 66
3.8. Формат элемента PTE (PDE). 69
3.9. Особенности страничного механизма в Pentium и Р6. 70
3.10 Механизм V86. 73
3.11 Методы обработки прерываний, возникших в режиме V86. 74
3.12 Механизм переключения задач. Формат сегмента TSS 77
3.13 Битовая карта ввода вывода 79
3.14 Действия процессора при переключении задач. 80
3.15 Формат дескриптора. 80
3.16 Форматы шлюзов 83
3.17 Программная модель 32 разрядного МП 84
3.18 Регистры системного программиста 86
3.19 Буфер TLB ( кэш-память страниц ) 89
3.20 Некоторые общие сведения о кэш-памяти 91
3.21 Внутренняя кэш-память 94
3.22 Сведения о кэшах в процессорах фирмы Intel. 95
3.23 Инициализация процессора 95
3.24 Некоторые сведения о внутренней организации 32 разрядных процессоров. 96
3.25 Режим SMM. 99
3.26 Система прерываний 32 разрядных процессоров. 99
3.27 Переключение из защищенного режима в реальный режим 104
3.28 Формат машинной команды. 105
3.29. Команда CPUID. 107
3.30 Краткие характеристики микропроцессорв фирмы Intel. 113
ЛИТЕРАТУРА 113