
Вопрос 19)
Классификация периферийных устройств
Периферийное устройство (ПУ) - устройство, входящее в состав внешнего оборудования микро-ЭВМ, обеспечивающее ввод/вывод данных, организацию промежуточного и длительного хранения данных.
Можно выделить следующие основные функциональные классы периферийных устройств. ПУ, предназначенные для связи с пользователем. К ним относят различные устройства ввода (клавиатуры, сканеры, а также манипуляторы - мыши, трекболы и джойстики), устройства вывода (мониторы, индикаторы, принтеры, графопостроители и т.п.) и интерактивные устройства (терминалы, ЖК-планшеты с сенсорным вводом и др.)
Устройства массовой памяти (винчестеры!), дисководы!), стримерыЗ) , накопители на оптических дисках, флэш-память4) и др.)
Устройства связи с объектом управления (АЦП, ЦАП, датчики, цифровые регуляторы, реле и т.д.) Средства передачи данных на большие расстояния (средства телекоммуникации) (модемы, сетевые адаптеры).
Внешняя память - это память, реализованная в виде внешних (относительно системной платы) устройств с разными принципами хранения информации и типами носителей, предназначенных для долговременного хранения данных. Устройства внешней памяти (накопители) могут размещаться как в системном блоке компьютера, так и в отдельных корпусах. Накопитель представляет собой совокупность носителя данных и соответствующего привода. Различают накопители со сменными и постоянными носителями.
Привод — это объединение механизма чтения-записи с соответствующими электронными схемами управления. Его конструкция определяется принципом действия и видом носителя. Носитель - это физическая среда хранения информации. По внешнему виду может быть дисковым или ленточным. По способу запоминания различают магнитные, оптические и магнитооптические носители. Леиггочные носители могут быть только магнитными. В дисковых носителях используют магнитные, магнитооптические и оптические методы записи/считывания информации.
Накопитель на жестких магнитных дисках (НЖМД, винчестер, HDD - Hard Disk Drive) -основное устройство хранения данных в персональных компьютерах, поскольку по объемам памяти не имеет аналогов среди других устройств хранения данных и, кроме этого, в НЖМД хранится операционная система, которая запускается при каждом включении компьютера. - электронно-механическое устройство.
ционная система или компиляторы часто принимают соглашения о том, каким образом используются эти регистры. Например, некоторые регистры могут содержать параметры вызываемых процедур, а другие могут использоваться в качестве временных регистров. Если компилятор помещает важную локальную переменную в регистр R1, а затем вызывает библиотечную процедуру, которая воспринимает регистр R1 как временный регистр, доступный для нее, то когда библиотечная процедура возвращает значение, регистр R1 может содержать ненужные данные. А если существуют какие-либо системные соглашения по поводу того, как нужно использовать регистры, составители компиляторов и программисты на языке ассемблера должны следовать им.
Кроме регистров, доступных на уровне команд, всегда существует довольно большое количество специальных регистров, доступных только в привилегированном режиме. Эти регистры контролируют различные блоки кэш-памяти, основную память, устройства ввода-вывода и другие элементы аппаратного обеспечения машины. Данные регистры используются только операционной системой, поэтому компиляторам и пользователям не обязательно знать об их существовании. Есть один регистр управления, который представляет собой привилегированно-пользовательский гибрид. Это флаговый регистр, или PSW (Program State Word — слово состояния программы. Этот регистр содержит различные биты, которые нужны центральному процессору. Самые важные биты — это коды условия. Они устанавливаются в каждом цикле АЛ У и отражают состояние результата предыдущей операции. Биты кода условия включают:
• N — устанавливается, если результат был отрицательным (Negative);
• Z — устанавливается, если результат был равен 0 (Zero);
• V — устанавливается, если результат вызвал переполнение (oVerflow);
• С — устанавливается, если результат вызвал выход переноса самого левого бита (Carry out);
• А — устанавливается, если произошел выход переноса бита 3 (Auxiliary carry — служебный перенос);
• Р — устанавливается, если результат четный (Parity).
Коды условия очень важны, поскольку они используются при сравнениях и условных переходах. Например, команда СМР обычно вычитает один операнд из
другого и устанавливает коды условия на основе полученной разности. Еслиоперанды равны, то разность будет равна 0 и во флаговом регистре будет установлен бит Z. Последующая команда BEQ (Branch Equal — переход в случае равенства) проверяет бит Z и совершает переход, если он установлен. Флаговый регистр содержит не только коды условия. Его содержимое меняется от машины к машине. Дополнительные поля указывают режим машины (например, пользовательский или привилегированный), трассовый бит (который используется для отладки), уровень приоритета процессора, а также статус разрешения прерываний. Флаговый регистр обычно можно считать в пользовательском режиме, но некоторые поля могут записываться только в привилегированном режиме (например, бит, который указывает режим). Прямая адресация
Следующий способ определения операнда — просто дать его полный адрес. Такой способ называется прямой адресацией. Как и непосредственная адресация, пря мая адресация имеет некоторые ограничения: команда всегда будет иметь доступ только к одному и тому же адресу памяти. То есть значение может меняться, адрес — нет. Таким образом, прямая адресация может использоваться только для доступа к глобальным переменным, адреса которых известны во время компиля ции. Многие программы содержат глобальные переменные, поэтому этот спосо широко используется. Каким образом компьютер узнает, какие адреса непосред ственные, а какие прямые, мы обсудим позже. Сравнения и условные переходы
Практически все программы должны проверять свои данные и на основе результатов изменять последовательность команд, которые нужно выполнить. Рассмотрим функцию квадратного корня Ох. Если число х отрицательное, процедура сообщает об ошибке; если число положительное, процедура вычисляет квадратный корень. Функция sqrt должна проверять х, а затем совершать переход в зависимости от того, положительно число х или отрицательно.
Это можно сделать с помощью специальных команд условного перехода, которые проверяют какое-либо условие и совершают переход в определенный адрес памяти, если условие выполнено. Иногда определенный бит в команде указывает,
нужно ли осуществлять переход в случае выполнения условия или в случае невыполнения условия соответственно. Часто целевой адрес является не абсолютным, а относительным (он связан с текущей командой).
Самое распространенное условие, которое нужно проверить, — равен ли определенный бит нулю или нет. Если команда проверяет знаковый бит числа и совершает переход к метке (LABEL) при условии, что бит равен 1, то если число было отрицательным, будут выполняться те утверждения, которые начинаются с метки LABEL, а если число было положительным или было равно 0, то будут выполняться те утверждения, которые следуют за условным переходом. Во многих машинах содержатся биты кода условия, которые указывают на особые условия. Например, там может быть бит переполнения, который принимает значение 1 всякий раз, когда арифметическая операция выдает неправильный результат. Проверяя этот бит, мы проверяем выполнение предыдущей арифметической операции, и если произошла ошибка, то запускается программа обработки ошибок.
В некоторых процессорах есть специальный разряд (бит) переноса, который принимает значение 1, если происходит перенос из самого левого бита (например, при сложении двух отрицательных чисел). Бит переноса нельзя путать с битом переполнения. Проверка бита переноса необходима для вычислений с повышенной точностью (то есть когда целое число представлено двумя или более словами). Операция сравнения слов или символов очень важна, например, при сортировке. Чтобы произвести сравнение, требуется три адреса: два нужны для элементов данных, а в третий адрес будет совершаться переход в случае выполнения условия. В тех компьютерах, где форматы команд позволяют содержать три адреса в команде, проблем не возникает. Но если такие форматы не предусмотрены, нужно что-то сделать, чтобы обойти эту проблему. Команды вызова процедур
Процедура — это группа команд, которая выполняет определенную задачу и которую можно вызвать из нескольких мест программы. Вместо термина процедура часто используется термин подпрограмма, особенно когда речь идет о программах на языке ассемблера. Когда процедура закончила задачу, она должна вернуться к
соответствующему оператору. Следовательно, адрес возврата должен как-то передаваться процедуре ил] сохраняться где-либо таким образом, чтобы можно было определить местонахождение после завершения задачи. Адрес возврата может помещаться в одном из трех мест: в памяти, в регистре или в стеке. Самое худшее решение — поместить этот адрес в одну фиксированную ячейку памяти. Тогда если процедура будет вызывать другую процедуру, второй вызов приведет к потере первого адреса возврата.
Более удачное решение — сохранить адрес возврата в первом слове процедуры. Тогда первой выполняемой командой будет второе слово процедуры. После завершения процедуры происходит переход к первому слову, а если аппаратное обеспечение в первом слове наряду с адресом возврата дает код операции, то происходит непосредственный переход к этой операции. Процедура может вызывать другие процедуры, поскольку в каждой процедуре имеется пространство для одного адреса возврата. Но если процедура вызывает сама себя, эта схема не работает, поскольку первый адрес возврата будет уничтожен вторым вызовом. Способность процедуры вызывать саму себя, называемая рекурсией, очень важна и для теоретиков, и для практиков. Более того, если процедура А вызывает процедуру В, процедура В вызывает процедуру С, а процедура С вызывает процедуру А (непосредственная или цепочечная рекурсия), эта схема сохранения адреса возврата также не работает. Еще более удачное решение — помещать адрес возврата в регистр. Если процедура рекурсивна, ей придется помещать адрес возврата в другое место каждый раз, когда она вызывается.
Самое лучшее решение — поместить адрес возврата в стек. Когда процедура завершена, она выталкивает адрес возврата из стека. При такой форме вызова процедур рекурсия не порождает никаких проблем; адрес возврата будет автоматически сохраняться таким образом, чтобы избежать уничтожения предыдущего адреса возврата. Мы рассматривали такой способ сохранения адреса возврата в машине ПУМ(см.рис.4.10).
Макросы
Программистам на языке ассемблера часто приходится повторять одни и те лее цепочки команд по несколько раз. Проще всего писать нужные команды всякий раз, когда они требуются. Но если последовательность достаточно длинная или
Кэш-память
Одним из самых важных вопросов при разработке компьютеров было и остается построение такой системы памяти, которая могла бы передавать операнды процессору с той же скоростью, с которой он их обрабатывает. Быстрый рост скорости работы процессора, к сожалению, не сопровождается столь же высоким ростом скорости работы памяти. Относительно процессора память работает все медленнее и медленнее с каждым десятилетием. С учетом огромной важности основной памяти эта ситуация сильно ограничивает развитие систем с высокой производительностью и направляет исследование таким путем, чтобы обойти проблему очень
низкой по сравнению с процессором скорости работы памяти. И, откровенно говоря, эта ситуация ухудшается с каждым годом. Современные процессоры предъявляют определенные требования к системе памяти и относительно времени ожидания (задержки в доставке операнда), и относительно пропускной способности (количества данных, передаваемых в единицу времени). К сожалению, эти два аспекта системы памяти сильно расходятся. Обычно с увеличением пропускной способности увеличивается время ожидания. Например, технологии конвейеризации, которые используются в микроархитектуре Mic-З, можно применить к системе памяти, при этом запросы/памяти будут обрабатываться более рационально, с перекрытием. Но, к сожалению, как и в микроархитектуре Mic-З,7 это приводит к увеличению времени ожидания отдельных операций памяти. С увеличением скорости задающего генератора становится все сложнее обеспечить такую систему памяти, которая может передавать операнды за один или два цикла. Один из способов решения этой проблемы — добавление кэш-памяти. Как мы говорили в разделе ПКэш-память() главы 2, кэш-память содержит наиболее часто используемые слова, что повышает скорость доступа к ним. Если достаточно большой процент нужных слов находится в кэш-памяти, время ожидания может сильно сократиться. Одной из самых эффективных технологий одновременного увеличения пропускной способности и уменьшения времени ожидания является применение нескольких блоков кэш-памяти. Основная технология — введение отдельнои/кэш-памяти для команд и отдельной для данных (разделенной кэш-памяти). Такая кэш-память имеет несколько преимуществ. Во-первых, операции могут начинаться независимо в каждой кэш-памяти, что удваивает пропускную способность системы памяти. Именно по этой причине в микроархитектуре Mic-1 нам понадобились два отдельных порта памяти: особый порт для каждой кэш-памяти. Отметим, что каждая кэш-память имеет независимый доступ к основной памяти. В настоящее время многие системы памяти гораздо сложнее этих. Между разделенной кэш-памятью и основной памятью часто помещается кэш-память второго уровня. Вообще говоря, может быть три и более уровней кэш-памяти, поскольку требуются более продвинутые системы. На рис. 4.25 изображена система с тремя уровнями кэш-памяти. Прямо на микросхеме центрального процессора находится небольшая кэш-память для команд и небольшая кэш-память для данных, обычно от 16 до 64 Кбайт. Есть еще кэш-память второго уровня, которая расположена не на самой микросхеме процессора, а рядом с ним в том же блоке. Кэш-память второго уровня соединяется с процессором через высокоскоростной тракт данных. Эта кэш-память обычно не является разделенной и содержит смесь данных и команд. Ее размер — от 512 Кбайт до 1 Мбайт. Кэш-память третьего уровня находится на той же плате, что и 19_>_3_процессор, и обычно состоит из статического ОЗУ в несколько мегабайтов, которое функционирует гораздо быстрее, чем динамическое ОЗУ основной памяти. Обычно все содержимое кэш-памяти первого уровня находится в кэш-памяти второго уровня, а все содержимое кэш-памяти второго уровня находится в кэшпамяти третьего уровня.
Существует два типа локализации адресов. Работа кэш-памяти зависит от этих типов локализации. Пространственная локализация основана на вероятности, что в скором времени появится потребность обратиться к ячейкам памяти, которые расположены рядом с недавно вызванными ячейками. Исходя из этого наблюдения в кэш-память переносится больше данных, чем требуется в данный момент.
Временная локализация имеет место, когда недавно запрашиваемые ячейки запрашиваются снова. Это может происходить, например, с ячейками памяти, находящимися рядом с вершиной стека или с командами внутри цикла. Принцип временной локализации используется при выборе того, какие элементы выкинуть изкэш-памяти в случае промаха кэш-памяти. Обычно отбрасываются те элементы, к которым давно не было обращений. /
Во всех типах кэш-памяти используется следующая модель. Основная память разделяется на блоки фиксированного размера, которые называются строками кэш-памяти. Строка кэш-памяти состоит из нескольких последовательных байтов (обычно от 4 до 64). Строки нумеруются, начиная с 0, то есть если размер строки составляет 32 байта, то строка О — это байты с 0 по 3'1, строка 1 — байты с 32 по 63 и т. д. В любой момент несколько строк находится в кэш-памяти. Когда происходит обращение к памяти, контроллер кэш-памяти проверяет, есть ли нужное слово в данный момент в кэшпамяти. Если есть; то можно сэкономить время, требуемое на доступ к основной памяти. Если данного слова в кэшпамяти нет, то какая-либо строка из нее удаляется, а вместо нее помещается нужная строка из основной памяти или из кэш-памяти бдлее низкого уровня. Существует множество вариаций данной схемы, но в их основе всегда лежит идея держать в кэил-памяти как можно больше часто используемых строк, чтобы число успешных обращений к кэш-памяти было максимальным. Директивы
Программа на языке ассемблера должна не только определять, какие машинные команды нужно выполнить, но и содержать команды, которые должен выполнять сам ассемблер (например, потребовать от него определить местонахождение какой-либо сохраненной информации или выдать новую страницу листинга). Команды для ассемблера называются псевдокомандами или директивами ассемблера. Мы уже видели одну типичную псевдокоманду DW (см. табл. 7.2). В табл. 7.5 приведены некоторые другие псевдокоманды (директивы). Они взяты из ассемблера MASM для семейства Intel.
Таблица 7.5. Некоторые директивы ассемблера MASM
Директива Значение
SEGMENT Начинает новый сегмент (текста, данных, и т п.) с определенными атрибутами ENDS Завершает текущий сегмент
ALIGN Контролирует выравнивание следующей команды или данных EQU Определяет новый символ, равный данному выражению DB Выделяет память для одного или нескольких байтов DD Выделяет память для одного или нескольких 16-битных полуслов DW Выделяет память для одного или нескольких 32-битных слов DQ Выделяет память для одного или нескольких 64-битных двойных слов PROC Начинает процедуру ENDP Завершает процедуру MACRO Начинает макроопределение ENDM Завершает макроопределение
PUBLIC Экспортирует имя, определенное в данном модуле EXTERN Импортирует имя из другого модуля INCLUDE Вызывает другой файл и включает его в текущий файл IF Начинает условную компоновку программы на основе данного выражения ELSE Начинает условную компоновку программы, если условие IF над директивой не выполнено
ENDIF Завершает условную компоновку программы COMMENT Определяет новый отделитель комментариев PAGE Совершает принудительный обрыв страницы в листинге END Завершает программу ассемблирования
Директива SEGMENT начинает новый сегмент, а директива ENDS завершает его. Разрешается начинать текстовый сегмент, затем начинать сегмент данных, затем переходить обратно к текстовому сегменту и т. д.
Директива ALIGN переводит следующую строку (обычно данные) в адрес, который делим на аргумент данной директивы. Например, если текущий сегмент уже содержит 61 байт данных, тогда следующим адресом после ALIGN 4 будет адрес 64. Директива EQU дает символическое название некоторому выражению. Например, после записи BASE EQU 1000 символ BASE можно использовать вместо 1000. Выражение, которое следует за EQU, может содержать несколько символов, соединенных арифметическими и другими операторами, например: LIMIT EQU 4 * BASE + 2000
Большинство ассемблеров, в том числе MASM, требуют, чтобы символ был определен в программе до появления в некотором выражении, сльких переменных размером 1, 2,4 и 8 байтов соответственно. Например,
TABLE D8 11. 23. 49 выделяет пространство для 3 байтов и присваивает им начальные значения 11, 23 и 49 соответственно. Эта директива, кроме того, определяет символ TABLE, равный тому адресу, где хранится число 11. Директивы PROC и ENDP определяют начало и конец процедур языка ассемблера. Процедуры в языке ассемблера выполняют ту же функцию, что и в языках программирования высокого уровня. Директивы MACRO и ENDM определяют начало и конец макроса. О макросах мы будем говорить ниже. Далее идут директивы PUBLIC и EXTERN. Программы часто пишут в виде совокупности файлов. Часто процедуре, находящейся в одном файле, нужно вызвать процедуру или получить доступ к данным, определенным в другом файле. Чтобы такие отсылки между файлами стали возможными, обозначение (имя), которое нужно сделать доступным для других файлов, экспортируется с помощью директивы PUBLIC. Чтобы ассемблер не ругался по поводу использования символа, который не определен в данном файле, этот символ может быть объявлен внешним (EXTERN), это сообщит ассемблеру, что символ определен в каком-то другом файле. Символы, которые не определены ни в одной из этих директив, используются только в пределах одного файла. Поэтому даже если символ FOO используется в нескольких файлах, это не вызовет никакого конфликта, поскольку этот символ локален по отношению к каждому файлу. Директива INCLUDE приказывает ассемблеру вызвать другой файл и включить его в текущий файл. Такие включенные файлы часто содержат определения, макросы и другие элементы, необходимые для разных файлов. Многие языки ассемблера, в том числе MASM, поддерживают условную компоновку программы. Например, программа WORDSIZE EQU 16 IF WORDSIZE GT 16
WSIZE: DW32 ELSE WSIZE: DW 16 ENDIF выделяет в памяти одно 32-битное слово и вызывает его адрес WSIZE. Этому слову придается одно из значений: либо 32, либо 16 в зависимости от значения WORDSIZE (в данном случае 16). Такая конструкция может использоваться в программах для 16-битных машин (как 8088) или для 32-битных машин (как Pentium II). Если в начале и в конце машинозависимого кода поставить IF и ENDIF, а затем изменить одно определение, WORDSIZE, программу можно автоматически установить на один из двух размеров. Применяя такой подход, можно сохранять одну такую исходную программу для нескольких разных машин. В большинстве случаев все машиноза висимые определения, такие как WORDSIZE, сохраняются в одном файле, причем для разных машин должны быть разные файлы. Путем включения файла с нужными определениями программу можно легко перекомпилировать на разные машины. Директива COMMENT позволяет пользователю изменять символ комментария на что-либо отличное от точки с запятой. Директива PAGE используется для управления листингом программы. Наконец, директива END отмечает конеи программы. Макросы 527 В ассемблере MASM есть еще много директив. Другие ассемблеры для Pentium II содержал другой набор директив, поскольку они определяются не в соответствии с архитектурой машины, а по желанию разработчиков ассемблера.
не конфликтуют с другими платами, затем пользователь должен открыть систем ный блок, аккуратно вставить плату, закрыть системный блок, а затем включит компьютер. Для многих этот процесс очень сложен и часто приводит к ошибкам Кроме того, число слотов ISA и PCI очень мало (обычно их два или три). Платы Plug and Play исключают установку переключателей, но пользователь все равно должен открывать компьютер и вставлять туда плату. К тому же количество слотов шины ограничено.
В середине 90-х годов представители семи компаний (Compaq, DEC, IBM, Intel, Microsoft, NEC и Nothern Telecom) собрались вместе, чтобы разработать шину, оптимально подходящую для подсоединения низкоскоростных устройств. Потом к ним примкнули сотни других компаний. Результатом их работы стала шина USB (Universal Serial Bus — универсальная последовательная шина), которая сей-\час широко используется в персональных компьютерах. Она подробно описана в книгах [7,144].