Состояние процессора, как конечного автомата, может быть однозначно описано состоянием его регистров, памяти и устройств ввода-вывода. При этом память и устройства ввода-вывода представляют собой массивы однотипных ячеек, а набор регистров процессорного ядра и команды, доступные для выполнения, часто существенно различаются.
Рассмотрим основные команды, присутствующие в широко распространенных процессорах.
1.5.1. Команды пересылки данных.
Команды пересылки данных осуществляют перемещение чисел из одного физического устройства хранения данных в другое. Под физическими устройствами понимаются регистры и элементы памяти, которые могут быть обобщены термином «переменные состояния процессора». Термин «перемещение» является устоявшимся, хотя в действительно происходит копирование данных из одного устройства в другое (т.е. без изменения состояния источника).
Команды обычно обозначаются мнемоникой mov(move, «перемещение») или ld (load, «загрузка»).
Например, команда moveax, ebx скопирует содержимое регистра ebx в регистр eax.
1.5.2. Арифметические и логические команды.
1.5.3. Команды управления процессом выполнения программы.
Команды управления процессом выполнения программы изменяют линейный порядок выполнения команд. Для этого им требуется адрес, с которого необходимо продолжить выполнение. Адрес может задаваться как непосредственно числом, так и указанием в команде на регистр, в котором хранится нужный адрес.
К этим командам относятся:
1. Команды безусловного перехода.
Такие команды принудительно передают управление на новый адрес, указанный в команде. Обычно они имеют мнемонику, производную от слов Jump («прыжок») или Branch – например, jmp, jp, br.
2. Команды условного перехода.
Эти команды выполняют переход при наличии определенного условия. Чаще всего этим условием является наличие определенного состояния флага. Если условие не выполняется, процессор продолжает последовательное выполнение команд. Мнемоника этих команд строится на основе мнемоники команд перехода с добавлением условия. Например, jc означает «переход, если установлен флаг переноса» (carryflag).
3. Команды вызова подпрограмм.
При вызове подпрограмм (который может быть условным или безусловным) дополнительно происходит сохранение адреса следующей команды на стеке. Например, для x86 указателем стека служит ESP. Распространенной мнемоникой является call.
4. Команды возврата из подпрограмм.
Команды возврата из подпрограмм выполняют действия, обратные вызову подпрограммы – снимают число со стека и переходят к этому адресу. Стандартной мнемоникой является ret.
1.5.4. Команды ввода-вывода.
Наиболее часто реализуемые команды ввода-вывода – inи out. Эти команды инициируют цикл обмена данными по внешней шине. Очевидным применением этих команд является организация интерфейса с внешним оборудованием. Электрически система организуется таким образом, чтобы обращение процессора к определенным адресам с помощью команд ввода и вывода формировало чтение данных из внешних устройств или запись данных туда.
1.5.5. Специальные команды.
К этим командам могут быть отнесены все команды, не попадающие в перечисленные группы. Например, команда nop («нет операции»), команды принудительной установки и сброса флагов и т.п.
1.5.6. Прерывания.
Под прерыванием понимается принудительное изменение порядка исполнения команд в силу наступления внешнего события или имитации такого события программными средствами. В последнем случае момент выполнения прерывания (называемого также программным прерыванием в противовес аппаратному прерыванию от внешнего источника) может быть определен непосредственно по тексту программы, и на первый взгляд не отличается от обычного вызова подпрограммы. Однако порядок действий, выполняемый процессором, и дополнительные требования, предъявляемые к подпрограмме, которой передается управления, отличаются от процесса вызова подпрограммы, поэтому с целью использования этого механизма многие процессоры имеют возможность вызова прерывания программными средствами.
Прежде всего, возможность перехода по прерыванию может регулироваться специальными флагами процессора. Это делается не только для большего удобства программиста, но и для исключения ситуаций, в которых процессор последовательно вызывает прерывания, не успевая завершить обработку одного запроса до прихода второго. Аппаратный запрет на обработку прерываний позволяет исключить такие ситуации.
1.5.7. Подходы к декодированию команд.
Рассматривая систему команд, можно заметить, что в зависимости от регистровой модели процессора и требуемой функциональности можно получить более или менее сложные правила представления кодов команд. Возвращаясь к рассмотрению процессора в виде программируемого конечного автомата, нетрудно понять, что для реализации требуемой функциональности требуется обеспечить реакцию процессорного ядра на все комбинации переходов от одного состояния к другому. Для процессора с симметричной регистровой архитектурой число таких комбинаций может оказаться очень большим. Поэтому следует использовать различные способы группировки, объединения команд по типам операций и/или по задействованным регистрам, чтобы упростить схемы дешифрации и уменьшить логический объем устройства. Одним из таких подходов является использование так называемого слабого кодирования.
Рассмотрим в качестве примера некую систему команд, составляемую в произвольном порядке без учета каких-либо закономерностей. Допустим, что операции сложения регистров r1 и r3 был поставлен в соответствии код 01, операции вычитания этих регистров – код 02, а операции ЛОГИЧЕСКОЕ И над r2 и r4 – код 03. Нетрудно убедиться, что при таком подходе отсутствует явная закономерность между кодом команды и типом исполняемой операции, набором регистров и дополнительными эффектами, оказываемыми командой на набор переменных состояния. Следовательно, для получения информации об этих эффектах код команды следует преобразовать в список изменений, которые происходят при ее выполнении. Правила преобразования могут оказаться достаточно сложными, и говорят, что команды сильно кодированы. В противовес этому примем, что в 16-разрядной команде биты 2-0 соответствуют номеру первого операнда, биты 5-3 – номеру второго операнда, а бит 6 соответствует признаку выполнения сложения, бит 7 – вычитания и т.д.
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
|
|
|
|
|
|
|
– |
+ |
Номер 2-го операнда |
Номер 1-го операнда |
Тогда, рассмотрев двоичное представление кода команды, можно сразу сказать, какие действия она выполняет. Наличие единиц в разрядах, соответствующих выполнению отдельных операций, однозначно определяет тип этих операций, а числа, составленные из групп разрядов (полей 5-3 и 2-0 в показанном примере) определяют номера регистров, выступающих в качестве операндов. Дополнительные сложные преобразования при этом не требуются, и с точки зрения цифровой схемотехники, отдельные разряды кода команды могут быть поданы непосредственно на входы управления мультиплексорами, выбирающими операнды из регистрового блока, и входы разрешения работы соответствующих арифметических и логических устройств. В данном случае можно говорить, что команды слабо кодированы.
На практике слабое кодирование в чистом виде имеет существенные недостатки, поскольку допускает представление взаимоисключающих действий. Например, над двумя операндами может быть выполнена либо операция сложения, либо вычитания, но не обе сразу. Тем не менее, приведенное выше представление отдельных разрядов команды вполне допускает наличие логических 1 одновременно в 6 и 7 разрядах команды. Поэтому слабое кодирование желательно применять в сочетании с сильным, как показано ниже.
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
00 – сложение 01 – вычитание 10 – логич. И и т.д. |
Номер 2-го операнда |
Номер 1-го операнда |
В данном случае разряды 7 и 6 образуют битовое поле, которое рассматривается как код операции, выполняемой над операндами, заданными в разрядах 5-0. Эти разряды по-прежнему напрямую кодируют номера регистров-операндов, но способ задания операций над ними больше не допускает кодирования взаимоисключающих действий: сложение кодируется как «00», вычитание – как «01» и т.д.
Ниже показан вариант сочетания сильного и слабого кодирования.
Биты |
17 |
16 |
15 |
14 |
13-0 |
LITL |
0 |
1 |
Младшее слово загружаемой константы |
||
LITH |
1 |
0 |
Старшее слово загружаемой константы |
||
LIT0 |
1 |
1 |
Младшее слово загружаемой константы, знакорасширяемой до 32 бит |
||
JMP |
0 |
0 |
0 |
1 |
Адрес безусловного перехода |
IF |
0 |
0 |
1 |
0 |
Адрес перехода, если установлен флаг нуля |
CALL |
0 |
0 |
1 |
1 |
Адрес вызываемой подпрограммы |