ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.01.2021
Просмотров: 160
Скачиваний: 1
Лекция 13
5.1.7.7. Ввод-вывод
Эта группа команд характеризуется наибольшим количеством особенностей для разных ЭВМ. В современных персональных компьютерах используются три различные схемы ввода-вывода:
-
программируемый ввод-вывод с активным ожиданием;
-
ввод-вывод с управлением по прерываниям;
-
ввод-вывод с прямым доступом к памяти.
Рассмотрим каждую из этих схем. Наиболее простым является программируемый ввод-вывод, который часто применяется в дешевых микропроцессорах (например, во встроенных системах). Эти процессоры обычно имеют одну команду ввода и одну команду вывода. Каждая из них выбирает нужное устройство ввода-вывода. Между фиксированным регистром в процессоре и выбранным устройством ввода-вывода передается один символ. Процессор должен выполнять определенную последовательность команд при каждом считывании или записи символа.
В качестве примера рассмотрим один из стандартных вариантов. Для каждого устройства (ввода и вывода) используется пара регистров: регистр состояния (РС) и регистр данных (РД). Каждый из них имеет уникальный адрес. Если используется ввод-вывод с распределением памяти, эти регистры являются частью адресного пространства, и могут считываться и записываться с помощью обычных команд. В противном случае для чтения и записи регистров устройств используются специальные команды ввода-вывода, например IN и OUT. В обоих случаях процессор анализирует готовность устройства (проверяя некоторые разряды РС) и при готовности считывает (при вводе) или записывает (при выводе) очередной байт или слово регистра данных.
Основной недостаток программируемого ввода-вывода заключается в том, что центральный процессор проводит большую часть времени в цикле ожидания готовности устройства. Такой процесс называется активным ожиданием.
Ввод-вывод с управлением по прерываниям избавляет процессор от активного ожидания. В этом режиме центральный процессор запускает устройство ввода-вывода и далее занимается своей работой. По завершении операции ввода/вывода устройство выдает запрос на прерывание. Разрешением прерываний управляет программа (т.е. фактически процессор), устанавливая, например, бит разрешения прерываний в регистре устройства. Во многих компьютерах сигнал прерывания порождается путем логического умножения (И) бита разрешения прерываний и бита готовности устройства. Если программа разрешает прерывание перед запуском устройства ввода-вывода, то прерывание произойдет сразу же, поскольку бит готовности будет равен 1. Таким путем можно произвести некоторую инициализацию процесса ввода-вывода. Если она не требуется, то устройство запускают сразу, а уж затем устанавливают бит прерывания. Запись данных в регистр состояния устройства не изменяет бита готовности, который обычно может только считываться.
Ввод-вывод с управлением по прерываниям - это существенный шаг вперед, но и он имеет недостатки. В частности, прерывание происходит для каждого передаваемого символа, что нерационально. Часто требуется обрабатывать результаты ввода лишь по заполнении целого буфера. Решение состоит в возвращении к программируемому вводу-выводу, но осуществляется он независимо отдельным устройством - контроллером прямого доступа к памяти (ПДП), который имеет прямой доступ к шине. Микросхема ПДП может иметь 4 регистра, которые загружаются выполняемой центральным процессором программой. Первый регистр хранит адрес памяти для обмена данными, второй - количество передаваемых байтов или слов. Третий регистр содержит номер или адрес соответствующего устройства ввода-вывода. Четвертый регистр сообщает, должны данные считываться с устройства или записываться на него.
При наличии контроллера ПДП центральному процессору достаточно инициализировать несколько регистров. После этого он может выполнять другую работу до тех пор, пока передача данных не завершится. По окончании передачи данных центральный процессор получает сигнал прерывания от контроллера ПДП. Некоторые контроллеры ПДП содержат два, три и более наборов регистров, которые могут управлять несколькими процессами передачи данных одновременно.
Этот режим также имеет недостатки. Если некоторое высокоскоростное устройство, например диск, будет запускаться контроллером ПДП, то потребуется много циклов шины для обращений к памяти. ПДП имеет более высокий приоритет на доступ к шине, чем центральный процессор, поскольку устройства ввода-вывода обычно не допускают задержек. Во время этих циклов центральный процессор будет простаивать. Ситуация отбирания контроллером ПДП циклов шины у центрального процессора называется захватом цикла. Тем не менее выигрыш от того, что не требуется обрабатывать прерывание при каждом передаваемом байте (слове), существенно перевешивает потери, происходящие из-за захвата циклов.
5.2. Примеры систем команд
В этом разделе мы кратко рассмотрим наборы команд трех машин: Pentium II, UltraSPARC II и picoJava II. Каждая из них имеет набор базовых команд, которые обычно порождаются компиляторами, а также команды, которые используются редко или только операционной системой. Мы будем рассматривать лишь базовые команды.
5.2.1. Команды процессора Pentium II
В нижеследующей таблице приведены наиболее распространенные команды с целыми числами, которые широко используются в настоящее время. Этот список не является полным (например, нет команд с плавающей точкой), однако он дает общее представление о том, какие операции может выполнять Pentium II.
Многие команды Pentium II обращаются к одному или к двум операндам, которые находятся в регистрах или в памяти. Большинство команд имеют несколько различных кодировок в зависимости от природы операндов. В таблице для операндов используются обозначения SRC - источник информации (SOURCE, не меняется данной командой), и DST - приемник (DESTINATION, изменяется командой). Существуют правила относительно того, что может быть источником, а что приемником, но мы здесь о них не говорим. Многие команды имеют три варианта: для 8-, 16- и 32-битных операндов соответственно. Они различаются по коду операции и/или по одному биту в команде. Здесь приведены в основном 32-битные команды.
Команды в таблице разделены на несколько групп. Первая содержит команды, перемещения данных. Ко второй относятся арифметические операции со знаком и без него. Для умножения и деления 64-битное произведение или делимое хранится в двух регистрах: ЕАХ (младшие биты) и EDX (старшие биты).
Третья группа включает двоично-десятичную арифметику. Здесь каждый байт рассматривается как две 4-битные десятичные цифры. Комбинации битов от 1010 до 1111 не используются. Такая форма хранения неэффективна, но она устраняет необходимость преобразовывать десятичные входные данные в двоичные и обратно. Эти команды широко используются в программах на языке COBOL.
Логические команды и команды сдвига манипулируют битами в слове или байте.
Следующие две группы связаны с проверкой, сравнением и осуществлением перехода в зависимости от полученного результата. Результаты проверки и сравнения хранятся в различных битах регистра EFLAGS. Значок Jxx заменяет набор команд, которые совершают условный переход в зависимости от результатов предыдущего сравнения (то есть в зависимости от битов в регистре EFLAGS).
В Pentium II есть несколько команд для загрузки, сохранения, перемещения, сравнения и сканирования цепочек символов или слов. Перед этими командами может стоять специальный префиксный байт REP (повторение), который заставляет команду повторяться до тех пор, пока не будет выполнено определенное условие (например, пока регистр ЕСХ, значение которого уменьшается на 1 после каждого повторения, не будет равен 0). Таким образом, различные действия (перемещение, сравнение и т. д.) могут производиться над произвольными блоками данных.
Последняя группа содержит команды, которые не вошли ни в одну из предыдущих групп. Это команды перекодирования, управления, ввода-вывода и остановки процессора.
Команды перемещения данных
MOV DST, SRC |
Перемещает SRC в DST |
PUSH SRC |
Помещает SRC в стек |
POP DST |
Выталкивает слово из стека и помещает его в DST |
XCHG DS1.DS2 |
Меняет местами DS1 и DS2 |
LEA DST, SRC |
Загружает действительный адрес SRC в DST |
CMOV DST, SRC |
Условное перемещение |
Арифметические команды
ADD DST, SRC |
Складывает SRC и DST |
SUB DST, SRC |
Вычитает SRC из DST |
MUL SRC |
Умножает ЕАХ на SRC (без знака) |
IMUL SRC |
Умножает ЕАХ на SRC (со знаком) |
DIV SRC |
Делит EDX:EAX на SRC (без знака) |
IDV SRC |
Делит EDX:EAX на SRC (со знаком) |
ADC DST, SRC |
Складывает SRC с DST и прибавляет бит переноса |
SBB DST, SRC |
Вычитает из DST величину (SRC + бит переноса) |
INC DST |
Прибавляет 1 к DST |
DEC DST |
Вычитает 1 из DST |
NEG DST |
Отрицает DST (вычитает DST из 0) |
Двоично-десятичные команды (операнд – в AL)
DAA |
Десятичная коррекция сложения |
DAS |
Десятичная коррекция вычитания |
ААА |
Коррекция кода ASCII сложения |
AAS |
Коррекция кода ASCII вычитания |
ААМ |
Коррекция кода ASCII умножения |
AAD |
Коррекция кода ASCII деления |
Логические команды
AND DST, SRC |
Логическая операция И над SRC и DST |
OR DST, SRC |
Логическая операция ИЛИ над SRC и DST |
XOR DST, SRC |
Логическая операция ИСКЛЮЧАЮЩЕЕ-ИЛИ над SRC и DST |
NOT DST |
Замещение DST дополнением до 1 |
Команды сдвига/циклического сдвига
SAL/SAR DST, # |
Арифметический сдвиг DST влево/вправо на # битов |
SHL/SHR DST, # |
Логический сдвиг DST влево/вправо на # битов |
ROL/ROR DST, # |
Циклический сдвиг DST влево/вправо на # битов |
ROL/ROR DST, # |
Циклический сдвиг DST по переносу на # битов |
Команды тестирования/сравнения
TST SRC1, SRC2 |
Логическое И, установка флагов |
CMP SRC1, SRC2 |
Установка флагов на основе вычитания SRC1-SRC2 |
Команды передачи управления
JMP ADDR |
Переход к адресу |
Jxx ADDR |
Условные переходы на основе флагов |
CALL ADDR |
Вызов процедуры по адресу |
RET |
Выход из процедуры |
IRET |
Выход из прерывания |
LOOPxx |
Продолжает цикл до удовлетворения определенного условия |
INT ADDR |
Инициирует программное прерывание |
INTO |
Совершает прерывание, если установлен бит переполнения |
Команды для операций над цепочками |
|
LODS |
Загружает цепочку |
STOS |
Сохраняет цепочку |
MOVS |
Перемещает цепочку |
CMPS |
Сравнивает две цепочки |
SCAS |
Сканирование цепочки |
Коды условия |
|
STC |
Устанавливает бит переноса в регистре EFLAGS |
CLC |
Сбрасывает бит переноса в регистре EFLAGS |
CMC |
Образует дополнение бита переноса в регистре EFLAGS |
STD |
Устанавливает бит направления в регистре EFLAGS |
CLD |
Сбрасывает бит направления в регистре EFLAGS |
STI |
Устанавливает бит прерывания в регистре EFLAGS |
CLI |
Сбрасывает бит прерывания в регистре EFLAGS |
PUSHFD |
Помещает регистр EFLAGS в стек |
POPFD |
Выталкивает содержимое регистра EFLAGS из стека |
LAHF |
Загружает АН из регистра EFLAGS |
SAHF |
Сохраняет АН в регистре EFLAGS |
Прочие команды |
|
SWAP DST |
Изменяет порядок байтов DST |
CWQ |
Расширяет ЕАХ до EDX ЕАХ для деления |
SWDE |
Расширяет 16-битное число в АХ до ЕАХ |
ENTER SIZE, LV |
Создает стековый фрейм заданного размера и уровня |
LEAVE |
Удаляет стековый фрейм, созданный командой ENTER |
NOP |
Пустая операция |
HLT |
Останов |
IN AL, PORT |
Переносит байт из порта в АЛУ |
OUT PORT, AL |
Переносит байт из АЛУ в порт |
WAIT |
Ожидает прерывания |
Pentium II имеет ряд команд-префиксов. Префикс - это специальный байт, который может ставиться практически перед любой командой (подобно WIDE в JVM). Префикс REP заставляет следующую команду повторяться до тех пор, пока регистр ЕСХ не примет значение 0. REPZ и REPNZ заставляют команду повторно выполняться, пока код выполнения условия Z не примет значение 1 или 0 соответственно. Префикс LOCK резервирует шину для всей команды, чтобы можно было осуществлять многопроцессорную синхронизацию. Другие префиксы используются для того, чтобы команда работала в 16-битном или 32-битном формате. При этом не только меняется длина операндов, но и переопределяются методы адресации.
5.2.2. Команды UltraSPARC II
Ниже приведены целочисленные команды пользовательского режима UltraSPARC II. Отсутствуют команды с плавающей точкой, управления (например, управление кэш-памятью, команды перезагрузки системы). Нет также команд, манипулирующих непользовательскими адресными пространствами, а также устаревших. Набор команд достаточно мал: UltraSPARC II - это процессор типа RISC.
Команды типа LOAD и STORE имеют варианты для 1, 2, 4 и 8 байтов. Если в 64-разрядный регистр загружается меньшее число, оно может быть расширено по знаку либо дополнено нулями. Существуют команды для обоих вариантов.
Следующая группа команд выполняет арифметические операции. Команды с буквами СС в названии устанавливают биты кода условия, другие - нет. Наличие двух вариантов дает больше возможностей компилятору в плане оптимального перемещения команд. Например, если есть команды А, В, С, причем А устанавливает коды условия, а В проверяет их, то компилятор не может вставить С между А и В, если С также устанавливает условные коды. Имеются команды умножения, а также деления со знаком и без знака.
Кроме этого, поддерживается специальный формат 30-битных чисел с автоматическим опознаванием типа данных за счет поля тега. Он используется для таких языков, как Smalltalk и Prolog, в которых тип переменных может меняться во время выполнения программы. При наличии таких чисел компилятор может породить команду ADD, а во время выполнения программы машина определяет, нужна ли в данном случае целочисленная команда ADD или команда ADD с плавающей точкой.
Группа команд сдвига включает одну команду сдвига влево и две команды сдвига вправо. Каждая из них имеет два варианта: 32-битный и 64-битный.
Команды загрузки
LDSB ADDR, DST |
Загружает байт со знаком (8 битов) |
LDUB ADDR, DST |
Загружает байт без знака (8 битов) |
LDSH ADDR, DST |
Загружает полуслово со знаком (8 битов) |
LDUH ADDR, DST |
Загружает полуслово без знака (16 битов) |
LDSW ADDR, DST |
Загружает слово со знаком (32 бита) |
LDUW ADDR, DST |
Загружает слово без знака (32 бита) |
LDX ADDR, DST |
Загружает расширенные слова (64 бита) |
Команды сохранения |
|
STB SRC, ADDR |
Сохраняет байт (8 битов) |
STH SRC, ADDR |
Сохраняет полуслово (16 битов) |
STW SRC, ADDR |
Сохраняет слово (32 битов) |
STX SRC, ADDR |
Сохраняет расширенное слово (64 бита) |
Арифметические команды |
|
ADD R1, S2, DST |
Сложение |
ADDCC |
Сложение с установкой кода условия |
ADDC |
Сложение с переносом |
ADDCCC |
Сложение с переносом и установкой кода условия |
SUB R1, S2, DST |
Вычитание |
SUBCC |
Вычитание с установкой кода условия |
SUBC |
Вычитание с переносом |
SUBCCC |
Вычитание с установкой кода переноса |
MULX R1, S2, DST |
Умножение |
SDIVX R1, S2, DST |
Деление со знаком |
UDIVX R1, S2, DST |
Деление без знака |
TADCC R1, S2, DST |
Сложение с использованием поля тега |
Команды сдвига/циклического сдвига |
|
SLL R1, S2, DST |
Логический сдвиг влево (32 бита) |
SLLX R1, S2, DST |
Логический сдвиг влево (64 бита) |
SRL R1, S2, DST |
Логический сдвиг вправо (32 бита) |
SRLX R1, S2, DST |
Логический сдвиг вправо (64 бита) |
SRA R1, S2, DST |
Арифметический сдвиг вправо (32 бита) |
SRAX R1, S2, DST |
Арифметический сдвиг вправо (64 бита) |
Логические команды |
|
AND R1, S2, DST |
Логическое И |
ANDCC |
Логическое И с установкой кода условия |
ANDN |
Логическое НЕ-И |
ANDNCC |
Логическое НЕ-И с установкой кода условия |
OR R1, S2, DST |
Логическое ИЛИ |
ORCC |
Логическое ИЛИ с установкой кода условия |
ORN |
Логическое НЕ-ИЛИ |
ORNCC |
Логическое НЕ-ИЛИ с установкой кода условия |
XOR R1, S2, DST |
Логическое ИСКЛЮЧАЮЩЕЕ ИЛИ |
XORCC |
Логическое ИСКЛЮЧАЮЩЕЕ ИЛИ с установкой кода условия |
XNOR |
Логическое ИСКЛЮЧАЮЩЕЕ НЕ-ИЛИ |
XNORCC |
Логическое ИСКЛЮЧАЮЩЕЕ НЕ-ИЛИ с установкой кода условия |