Реклама:

Ни одна другая группа команд не различается в разных машинах так сильно, как команды ввода-вывода. В современных персональных компьютерах используются три разные схемы ввода-вывода:

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

+ ввод-вывод с управлением по прерываниям;

+ ввод-вывод с прямым доступом к памяти.

Мы рассмотрим каждую из этих схем по очереди.

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

В качестве примера рассмотрим терминал с четырьмя 1-байтными регистрами, как показано на рис. 5.20. Два регистра используются для ввода: регистр состояния устройства и регистр данных. Два регистра используются для вывода:

тоже регистр состояния устройства и регистр данных. Каждый из них имеет уникальный адрес. Если имеет место ввод-вывод с отображением на память, все 4 регистра являются частью адресного пространства и могут считываться и записываться с помощью обычных команд, предназначенных для работы с памятью. В противном случае для чтения и записи регистров требуются специальные команды ввода-вывода, например IN и OUT. В обоих случаях ввод-вывод осуществляется путем передачи данных и информации о состоянии устройства между центральным процессором и указанными регистрами.

Команды ввода-вывода

Рис. 5.20. Регистры устройств в простом терминале

В регистре состояния клавиатуры из 8 бит используются только 2. Самый левый бит аппаратно устанавливается всякий раз, когда в буфере клавиатуры появляется символ. Если предварительно программно был установлен бит 6, выполняется прерывание. В противном случае прерывания не происходит. При программируемом вводе-выводе для получения входных данных центральный процессор обычно периодически в цикле считывает регистр состояния клавиатуры, пока бит 7 не получит значение 1. Когда это случается, программно считыва-ется буферный регистр клавиатуры, чтобы получить символ. Считывание регистра данных вызывает сброс бита наличия символа.

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

В качестве примера программируемого ввода-вывода рассмотрим тауа-про-цедуру (листинг 5.5). Эта процедура вызывается с двумя параметрами: массивом символов, которые нужно вывести, и количеством символов, имеющимся в массиве (до килобита). Тело процедуры представляет собой цикл, в котором выводится по одному символу. Сначала центральный процессор ждет готовности устройства и только после этого выводит символ, и эта последовательность действий повторяется для каждого символа. Процедуры in и out - это типичные процедуры ассемблера для чтения и записи регистров устройств, которые определяются по первому параметру. Переменная, из которой выполняется чтение или в которую производится запись, определяется по второму параметру. Деление на 128 (путем сдвига вправо на 7 разрядов) ликвидирует младшие 7 бит, при этом бит готовности оказывается в нулевом разряде.

Листинг 5.5. Пример программируемого ввода-вывода

public static void output_buffer(int buf[], int count) { // Вывод блока данных на устройство int status, i, ready;

for (i = 0; i<count; i++) { do {

status = in(display_status_reg); // получение информации

// о состоянии устройства ready = (status " 7) & 0x01; // выделение бита

// готовности

} while (ready == 1); out(display_buffer_reg, buf[i]);

}

}

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

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

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

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

Решение лежит в возвращении к программируемому вводу-выводу, но только эту работу вместо центрального процессора должен делать кто-то другой. Посмотрите на рис. 5.21. Мы добавили новую микросхему - контроллер прямого доступа к памяти (ПДП), имеющий непосредственный доступ к шине.

Команды ввода-вывода

Рис. 5.21. Система с контроллером прямого доступа к памяти

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

Чтобы записать блок из 32 байт с адреса памяти 100 на терминал (например, устройство 4), центральный процессор записывает числа 32, 100 и 4 в первые три регистра ПДП, а код записи (например, 1) - в четвертый регистр, как показано на рис. 5.21. Контроллер ПДП, инициализированный таким образом, делает запрос на доступ к шине, чтобы считать байт 100 из памяти, точно так же, как если бы этот байт считывал центральный процессор. Получив нужный байт, контроллер ПДП посылает устройству 4 запрос на ввод-вывод, чтобы записать на него байт. После завершения этих двух операций контроллер ПДП увеличивает значение регистра адреса на 1 и уменьшает значение регистра счетчика на 1. Если значение счетчика остается положительным, следующий байт считывается из памяти и записывается на устройство ввода-вывода.

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

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

Управление циклами || Оглавление || Команды процессора Pentium 4