Работа микропроцессора с внешними устройствами
Выше было описано, как процессор обменивается информацией с ее наиболее важным и оперативным источником - памятью. Рассмотрим теперь, как МП может принять данные или передать их внешним устройствам. Способ решения этой задачи в зависимости от конструкции ЭВМ (подчеркнем: не от конструкции МП, а от конструкции всей ЭВМ!) может быть одним из двух указанных ниже:
1) устройства ввода-вывода включаются в общее адресное пространство;
2) устройства ввода-вывода имеют собственное адресное пространство.
В первом случае при обращении к определенным адресам памяти вместо обмена с ОЗУ происходит аппаратное подключение того или иного внешнего устройства. При этом для «общения» с внешними устройствами и с памятью используются одни и те же команды МП, хотя, конечно, обмен с внешним устройством протекает по более сложному протоколу, чем с памятью.
Во втором случае внешние устройства образуют отдельное адресное пространство, обычно значительно меньшее, чем у ОЗУ. Каждая ячейка этого дополнительного адресного пространства называется портом. Каждому внешнему устройству обычно соответствует несколько портов с последовательными адресами. Обмен процессора с организованными подобным образом устройствами осуществляется специальными командами ввода-вывода.
На самом деле, с точки зрения схемной организации оба описанных способа имеют очень много общего. При любом обмене, будь то обращение к ОЗУ, ПЗУ или внешнему устройству, процессор выставляет адрес информации на единую адресную шину, а данные передает или принимает по общей шине данных. Выбор же требуемого адресата - ячейки памяти или порта - осуществляется подачей специального управляющего сигнала.
В одном и том же компьютере могут встречаться оба способа адресации устройств ввода-вывода одновременно. Так, в ПЭВМ «Ямаха» накопитель на магнитных дисках включен в общее адресное пространство памяти, а печатающее устройство оформлено в виде нескольких портов. Некоторые порты этого компьютера служат для подключения к небольшому 64-килобайтному адресному пространству 128 кбайт ОЗУ и многочисленных ПЗУ. При этом все ресурсы памяти разбиваются на отдельные страницы по 16 кбайт каждая, и «активными» в каждый момент времени могут быть только четыре из них.
Рассказ о работе с периферийными устройствами был бы неполным без описания того диалога, который ведет с ними МП. Рассмотрим этот диалог на примере простейших устройств ввода-вывода - например, печатающего устройства.
Обмен с подключенным к ЭВМ печатающим устройством производится через два основных порта - порт состояния и порт данных. В первом хранится информация о состоянии устройства в данный момент времени, а во второй МП помещает данные для вывода на бумагу. Каждый бит порча состояния хранит ответ на вполне определенный вопрос: заправлена ли бумага, готов ли принтер принять данные от компьютера и т.д. Все это для МП - входные сигналы. Но есть и выходные, которые через порт передаются от МП к печатающему устройству. Наиболее важным из них является бит, свидетельствующий о готовности информации в порту данных к передаче. Этот управляющий сигнал часто называют стробом.
В наиболее простом случае обмен информацией между процессором и принтером может протекать следующим образом. Пусть МП должен вывести на печать какой-нибудь символ. Он считывает порт состояния принтера и анализирует содержимое его бита готовности. Если результат положительный, т.е. печатающее устройство готово принять информацию, обмен продолжается, в противном случае МП снова считывает порт состояния и повторяет анализ. Когда процессор получит от принтера сигнал о готовности к обмену, он заносит требуемый символ в порт данных и установкой стробирующего сигнала сообщает об этом принтеру. Затем МП снова периодически считывает порт состояния, но следит уже за другим битом (через этот бит принтер сообщит процессору о том, что данные приняты, т.е. скопированы в собственное ОЗУ принтера). После этого МП убирает стробирующий потенциал и продолжает работу по программе.
Конечно, реальный диалог современного компьютера с печатающим устройством сложнее. Вот пример. Вы, наверное, заметили, что описанный выше алгоритм «зациклится», если принтер не подключен или не готов к работе: процессор будет ждать сигнала о готовности принтера, а того не будет. Выход - ожидать сигнала готовности в течение какого-то времени, а затем выдать пользователю сообщение о неготовности принтера к работе. При этом желательно проверить содержимое других битов порта состояния (например, отвечающих за наличие бумаги и т.п.) и уточнить, если потребуется, диагностическое сообщение.
Обмен информацией между МП и устройством ввода следует рассмотреть отдельно, так как он может иметь некоторые существенные особенности. Описанная выше идеология передачи данных, конечно, может быть использована и для устройств ввода - например, для клавиатуры. В этом случае программа в тот момент, когда ей потребуются входные данные, опросит состояние клавиатуры и примет с нее данные. Однако для сложных современных программных систем такой метод неудобен из-за существенного замедления времени реакции ЭВМ. В самом деле, если некоторая сложная программа занята вычислениями, а вы хотите ее прервать, то придется подождать, пока процессор освободится и займется опросом клавиатуры (собственно говоря, тогда и прерывать-то будет нечего!). Все это сильно напоминает очередь в приемной бюрократа-начальника, когда люди вынуждены часами ждать, пока их вызовут для пятиминутного решения вопроса.
Для предотвращения подобных неприятностей во всех ЭВМ на базе МП наряду с программным опросом устройств ввода существует еще один механизм - механизм прерывания от внешних устройств. Такие прерывания настолько широко используются в компьютерах, что имеет смысл рассмотреть их подробнее. Для понимания сути работы прерываний снова обратимся к аналогии с руководителем. Пусть в его кабинете идет совещание по подведению итогов деятельности предприятия, и в этот момент по телефону поступает очень важная информация, требующая немедленного принятия решения. Как в таком случае обычно развиваются события? Секретарь, не дожидаясь конца совещания, сообщает шефу о звонке. Тот, прервав свое выступление, снимает трубку и выясняет суть дела. Затем он либо тут же принимает решение и сообщает его, либо предлагает пока сделать самое необходимое, а после совещания обещает перезвонить и дать дальнейшие указания. Затем (обратим внимание на эту деталь!) он произносит что-нибудь в духе «Так, на чем мы остановились?» и продолжает совещание как ни в чем не бывало. Впрочем, если ситуация экстренная, то совещание может быть прекращено или в его ход могут быть внесены определенные коррективы.
Вернемся к компьютеру. Каждое его устройство (клавиатура, мышь, дисковод и др.) способно затребовать внимание процессора, выставляя сигнал требования прерывания. Процессор проверяет наличие этого сигнала после выполнения каждой операции. «Увидев» требование прерывания, МП немедленно начинаетего обрабатывать. Прежде всего, он запоминает свое текущее состояние (счетчик команд и регистр состояния) с тем, чтобы в дальнейшем иметь возможность продолжить выполнение прерванной программы. После этого происходит переход на программу, обрабатывающую данное прерывание. Заметим, что все перечисленные действия реализуются на аппаратном уровне, т.е. фактически являются «врожденными рефлексами» МП.
Программа обработки прерывания, получив управление, проводит оперативный анализ причины прерывания. Если причина серьезная и требует немедленных действий, то эти действия выполняются. Если же с обработкой можно подождать (например, просто нажата обычная символьная клавиша), в специальную область памяти (буфер) заносится информация о происшедшем прерывании. Во всех случаях прерывания завершаются выполнением специальной команды возврата, которая восстанавливает содержимое программного счетчика и регистра состояния, давая тем самым микропроцессору возможность продолжить работу прерванной программы. Естественно, что программа обработки прерывания должна была предварительно восстановить все испорченные ей рабочие регистры МП.
Реальная картина, конечно, еще сложнее: прерывания от разных устройств имеют разные уровни приоритета, существует возможность маскировки прерываний и т.п. Однако сути дела все это существенно не меняет.
В последнее время необходимость понимания механизма работы прерываний сильно возросла в связи с возникновением идеологии программирования по событиям. Она связана с распространением среды «Windows» и лежит в основе систем типа «Visual Basic» или «Delphi». Приведем примеры нескольких событий, на которые программа может реагировать: сдвинута мышь, нажата (или отпущена) клавиша мыши, нажата клавиша «ввод», выбран тот или иной пункт меню, открыто новое окно на экране и многие-многие другие. Полный перечень событий занимает в описании несколько страниц. Интересно, что программа на таком языке уже не является единым целым: на каждое событие пишется своя собственная программа, хотя все они и могут быть связаны между собой.
Итак, мы рассмотрели наиболее общие принципы работы микропроцессоров вне зависимости от их модели. Теперь познакомимся с конкретными процессорами.
ПРИМЕР: СИСТЕМА КОМАНД ПРОЦЕССОРОВ СЕМЕЙСТВА PDP
В качестве примера реально существующего процессора, удобного для более детального изучения, возьмем процессор серии машин, созданных фирмой DEC (США) и известных под названием PDP-11 (в нашей стране аналогичные процессоры использовались в семействах 16-разрядных мини- и микро-ЭВМ «Электроника», ДВК, БК, а также в школьном компьютерном классе УКНЦ; всего таких машин было выпущено в СССР до 1,3 млн. штук и примерно столько же в США). Это семейство мини- и микро-компьютеров - одно из самых долгоживущих: первая машина этой серии была выпущена в 1970 г., а прекращение выпуска было запланировано фирмой DEC на 1997 г.
Причина выбора процессора PDP для иллюстрации обсуждаемого вопроса состоит в том, что система команд этого процессора построена на простых и наглядных принципах, изучив и запомнив которые уже можно составлять несложные программы. В то же время система команд других процессоров, например, широко распространенных представителей семейства «Intel», устроена значительно сложнее, требует запоминания большого количества справочных данных. В качестве подтверждения сказанного достаточно указать, что в команде процессора PDP может быть использован любой из имеющихся внутренних регистров, тогда как многие команды процессоров «Intel» оперируют с фиксированными регистрами, не допуская альтернативного расположения данных и результатов.
Процессор машин серии PDP и его отечественные аналоги (при дальнейшем изложении будем все это обширное семейство для краткости называть «процессор PDP») с точки зрения программиста устроен довольно просто. Он состоит из восьми регистров общего назначения (РОН) и особого регистра, в котором отображается текущее состояние процессора (в иностранной литературе его принято обозначать PSW - Processor Status Word). Любой из регистров общего назначения может быть использован в командах на равных основаниях. Вместе с тем имеются два выделенных регистра, содержимое которых процессор использует для собственных нужд. Прежде всего следует назвать регистр R7, выполняющий роль счетчика команд, в котором хранится адрес следующей инструкции программы. Другим выделенным регистром является указатель стека R6, используемый при запоминании информации в момент вызова подпрограмм и при переходе к обработке прерывания.
Остальные 6 регистров, обозначаемые RO, Rl. R2, R3, R4, R5, программист может полностью использовать по своему усмотрению. Имеется только одно (непринципиальное) исключение: в обширной системе команд PDP существует лишь единственная, и то достаточно экзотическая, команда (MARK), работающая с регистром R5.
Следует отметить, что и выделенные регистры процессора R6 и R7 могут быть использованы в любой команде наряду с обычными РОН RO-R5. Например, допускается переписать информацию из R7 в R3 и тем самым сообщить программе адрес памяти, в котором находится следующая команда программы. Такой прием очень часто используется программистами для автоматической «самонастройки» на те адреса ОЗУ, в которых оказалась загруженной программа. Интересно, что такого простого доступа к содержимому программного счетчика многие процессоры не имеют.
Рис. 4.14. Схема регистра состояния процессора PDP
Регистр состояния процессора PSW, как и все РОН, является 16-битным. Его особенностью является то, что каждый его бит имеет самостоятельное значение и может использоваться процессором отдельно от других. В управляющих битах регистра постоянно отображается информация о выполняемых результатах (отрицательность, равенство нулю и т.п.), а также о состоянии процессора в данный момент (например, один из битов позволяет разрешать или запрещать обработку прерывании). Из всех используемых битов (не все 16 бит регистра состояния задействованы!) наиболее используемы два; их принято обозначать N и Z. Управляющий признак N (Negative) отражает знак результата операций: если число отрицательное, то N = 1, неотрицательное - N = 0. Бит Z (Zero) говорит о равенстве или неравенстве нулю результата: в первом случае Z = 1, во втором - Z = 0. Путем несложных рассуждений можно убедиться в том, что из шести известных математических соотношений
=, < , > , ≤ , ≥ , ≠
четыре могут быть проанализированы по одному из признаков, а два оставшихся требуют совместного анализа битов N и Z.
Другие управляющие биты, изображенные на рисунке, используются следующим образом. Бит Р - задание маскировки прерываний от внешних устройств (Р = 0 -прерывание состоится. Р = 1 - замаскировано). Бит Т - «признак ловушки»; при Т = 1 после прерывания запускается специальная системная программа, позволяющая на этапе отладки текущей программы осуществлять режим трассировки. Бит V -признак переполнения разрядной сетки при арифметической операции (если это произошло, устанавливается V = 1); бит С - аналогично при переполнении разрядной сетки при логической операции, сопровождаемой сдвигом кода. Описанные управляющие признаки широко используются для реализации разветвлений программы в зависимости от полученных результатов, анализа причин прерываний и других действий.
Процессор PDP имеет достаточно удобный и широкий набор команд. Основная их часть является двухадресными и одноадресными, т.е. они обрабатывают два или один операнд, соответственно. Для выполнения некоторых управляющих команд данные не требуются (например, команда остановки программы) - такие команды не содержат ссылок на операнды. Форматы одно- и двухадресных команд изображены ниже на рис. 4.15.
КОП | КМА | N POH | ||
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | ||||
КОП | KMA1 | N POH1 | KMA2 | N POH2 |
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | ||||
Рис.4.15. Формат одноадресной команды (вверху) и двухадресной (внизу). КОП - код операции. КМА - код метода адресации, N РОН - номер регистра общего назначения (код адреса)
Примеры некоторых наиболее важных операций приведены в табл. 4.2. Действия, выполняемые по простейшим арифметическим операциям, понятны из пояснений. В некоторых дополнительных пояснениях нуждаются только команды переходов.
Во-первых, переходы бывают абсолютные (на заданный адрес) и относительные (на определенное число команд относительно данной). Переходы первого типа более наглядны и могут быть реализованы на любой адрес ОЗУ. Относительные переходы требуют вычисления адреса перехода, зато они не привязаны к конкретным адресам ОЗУ: программа, использующая относительные переходы, может работать в любом месте памяти. Относительные переходы занимают меньше места в памяти, чем абсолютные; вследствие этого диапазон относительных переходов ограничен (в процессоре PDP только на 127 слов вперед и 128 - назад).
Таблица 4.2