Project

General

Profile

Система команд(Instruction Set Architecture) » History » Version 2

Version 1 (krufter_multiclet, 04/24/2013 02:17 PM) → Version 2/3 (krufter_multiclet, 07/11/2013 05:36 PM)

h1. Система команд (Instruction Set Architecture)

h3. Формат кодирования команды

Формат AA размер 32 бит:

<pre>

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
. . . . . . . . . . . . . . . . . . . . . . . . . . X X X X X X -- F2 -- адрес значения 2-ого операнда
. . . . . . . . . . . . . . . . . . . . X X X X X X -------------------- F1 -- адрес в коммутаторе значения 1-ого операнда
. . . . . . . . . . . . . . X X X X X X -------------------------------------- t -- Задержка выдачи результата (тау).
. . . . . . . . . . . . . X -------------------------------------------------------- Резерв.
. . . . . . . . . . . . X ---------------------------------------------------------- Признак инструкции, завершающей параграф.
. . . . . . . . X X X X -------------------------------------------------------------- TOP -- тип операции.
. . . . . . X X -------------------------------------------------------------------------- Суффикс:
. . . . . . 0X - формат AA
. . . . . . 00 - F2 содержит адрес коммутатора
. . . . . . 01 - F2 содержит номер регистра
. . . . . . 11 - F2 номер индексного регистра
X X X X X X -------------------------------------------------------------------------------- COP -- код операции.
</pre>

Формат AV размер 64 бит.
Старшая часть имеет такую же структуру как и формата AA, младшие 32 бита -- значение поля V.

*= Типы операций =*

Тип операции задается кодом в поле `TOP`.

Правило кодирования типов содержащих значение в целочисленном представлении.

<pre>
3 2 1 0
. . x x -- Уменьшенный на единицу размер в байтах:
. . 00 - byte
. . 01 - half word
. . 10 - word
. . 11 - double word
. 0 ------ Признак представления плавающей точки, всегда == 0.
x -------- Признак знаковости:
0 - Беззнаковое;
1 - Знаковое.
</pre>

Правило кодирования типов содержащих значение в представлении плавающей точки.

<pre>
3 2 1 0
. . x x -- Тип:
. . 00 - float
. . 01 - double
. . 10 - pack
. . 11 - complex
. 1 ------ Признак представления плавающей точки, всегда == 1.
1 -------- Признак знаковости, всегда == 1.
</pre>

Сводная таблица кодов типов.
|| '''Тип''' || '''Беззнаковый''' || '''Знаковый''' || '''Примечание''' ||
|| byte || 0b0000 || 0b1000 || ||
|| hword || 0b0001 || 0b1001 || Тип не используется в существующей реализации ||
|| word || 0b0010 || 0b1010 || ||
|| dword || 0b0011 || 0b1011 || Знаковый тип этого размера не используется в существующей реализации ||
|| || || ||
|| float || || 0b1100 || ||
|| double || || 0b1101 || Тип не используется в существующей реализации ||
|| pack || || 0b1110 || ||
|| comlex || || 0b1111 || ||

h3. === Типы в ассемблере ===

Для резервирования памяти данных в ассемблере используются директивы резервирования памяти, используемые в сегменте данных (.data).

Соответствие размера резервируемой памяти директивами ассемблера коду типов операции архитектуры приведено в таблице ниже.
Необходимо понимать, что директивы резервирования памяти в сегменте данных ассемблера никак не связаны с кодом типа операции.
Соответствие определить можно, но одно от другого не зависит.

|| '''Код типа''' || '''Директива''' || '''Размер в битах''' ||
|| byte || .byte || 8b ||
|| hword || .short || 16b ||
|| word || .long || 32b ||
|| dword || .quad || 64b ||

В ассемблере зависимость от кода типа данных появляется в мнемонике инструкции.
Мнемоника инструкции состоит из двух частей:
1. корня, соответствующего коду операции и
2. суффикса, соответствующего типу операции.

Операций системы команд будут представлены ниже, а мнемонику суффикса показывает следующая таблица:

|| '''TOP''' || '''Беззнаковый''' || '''Знаковый''' || '''Примечание''' ||
|| byte || b || sb || ||
|| hword || s || ss || НЕ используется в существующей реализации ||
|| word || l || sl || ||
|| dword || q || sq || Знаковый тип этого размера НЕ используется в существующей реализации ||
|| || || || ||
|| float || || f || ||
|| double || || d || НЕ используется в существующей реализации ||
|| pack || || p || ||
|| comlex || || c || ||

*==Поле регистров==*

Процессор имеет следующие типы регистров:
- регистры общего назначения (РОН [GPR -- General Purpose Register]);
- регистры индексные (РИ [IR -- Index Register]);
- регистры управляющие (РУ [CR -- Control Register]).

<pre>
5 4 3 2 1 0
. . X X X X -- Номер регистра.
X X ---------- Тип регистра:
00 -- Регистр общего назначения.
01 -- Зарезервировано, не используется.
10 -- Регистр индексный.
11 -- Регистр управляющий.
</pre>

h3. === Регистры общего назначения ===

Используются в качестве сверхбыстрой памяти (Scratchpad memory).
Имеют размер 64 бита.

h3. === Регистры индексные ===

Имеют следующую логическую структуру:

<pre>
63 .. 48 47 .. 32 31 .. 0
. . . . . . XXXXXX -- База (Base).
. . . XXXXXXX ---------- Маска (Mask).
XXXXXXX ------------------- Индекс (Index).
</pre>

При записи значения в индексный регистр одновременно устанавливаются все части регистра.

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

При этом, после выполнения параграфа в котором существует инструкция, использующая индексный регистр происходит модификация значения индексного регистра по следующей формуле:

На псевдо-Си:

<pre>
Index := (( Index | ~Mask ) + 1 ) & Mask
Base := Base + Index;
Операции сложения выполняются по модулю.
</pre>

Используются для определения смещения при индексном доступе к оперативной памяти.
В общем случае, для организации цикла используются два индексных регистра.
Один -- для вычисления количества итераций цикла, второй -- для вычисления смешения на каждом цикле итерации.
Шаг смещения, в простейшем случае, является степенью двойки (1,2,4,8,16,...).

*=== Регистры управляющие ===*

|| '''Имя регистра''' || '''Номер''' || '''Права''' || '''Описание''' ||
|| PSW || 00 || R/W || Регистр управления вычислительным процессом ||
|| INTR || 01 || R/W || Регистр прерываний ||
|| MSKR || 02 || R/W || Регистр маска прерываний ||
|| ER || 03 || R || Регистр исключений ||
|| IRETADDR || 04 || R || Регистр адреса возврата ||
|| STVALR || 05 || R/W || Регистр периода системного таймера ||
|| STCR || 06 || R/W || Регистр управления системным таймером ||
|| IHOOKADDR || 07 || R/W || Регистр первичного обработчика прерываний ||
|| INTNUMR || 08 || R || Регистр номера прерывания ||
|| MODR || 09 || R/W || Регистр маски модификации индексных регистров ||

h3. == Память ==

Единицей адресации памяти данных является байт, размером 8 бит.
Адресация по всем блокам памяти данных сквозная.
При этом аппаратно чтение данных выравнено на 64 бита.
При вычитывании данных пересекающих границу выравнивания чтение выполняется в "два приема" (сказывается на быстродействии).

Многобайтные значения в памяти данных располагаются в порядке от старшего байта к младшему (little-endian).

Единицей адресации памяти команд является 64 бита.
Адресация памяти команд блочная.
С программной точки зрения значение метки одинаково во всех блоках.

Значения в блоке памяти команд располагаются в порядке от младшего байта к старшему (big-endian).

*== Таблица команд ==*

Большинство инструкций формируют результат, сохраняемый в коммутаторе.
Размер значения результата соответствует размеру коммутатора -- 64 бит.

Результат нагружен значениями флагов:
|| '''№ бита''' || '''Флаг''' || '''Перевод''' || '''Описание''' ||
|| 64 || ZF (Zero Flag) || Флаг нуля || Результат нулевой. ||
|| 65 || OF (Overflow Flag) || Флаг переполнения || Потеря значащего бита. ||
|| 66 || CF (Carry Flag) || Флаг переноса || Операция произвела перенос из старшего бита результата. ||
|| 67 || SF (Sign Flag) || Флаг знака || Состояние старшего бита результата. ||

Флаги могут иметь значение не для каждой операции.
В таблице команд приведены значения флагов, которые имеют значение.

Обозначения, используемые в таблице команд:
- Все числа представлены в двоичной системе;
- Рядом с двоичным значением кода операции в скобочках дано десятичное значение;
- Если число или цифра не используется то на ее знакоместе стоит знак '-';
- Если цифра в числе может принимать любое значение, на ее знакоместе стоит знак 'x';
- В колонке флаги результата (Result Flags) перечислены флаги которые вырабатывает инструкция или которые она сохраняет.
Т.е. эти флаги, как характеристики значения результата, имеют смысл.
- Примечания, помеченные символом '*' для не реализованных в аппаратуре типов приведены для общности.

h3. === Инструкции работы с памятью ===

|| || COP || Suffix || TOP || F1 || F2 || Result Flags || Примечание ||
|| || || || || || || || ||
|| rd || 100001 (33) || xx || 00xx || 000000 || xxxxxx || ZF SF || Считывается столько бит сколько определено размером типа. Старшие биты нули. ||
|| || || xx || 1000 || 000000 || xxxxxx || ZF SF || Считываются 8 бит. 7 бит распространяется в старшие. ||
|| || || xx || 1001 || 000000 || xxxxxx || ZF SF || *Считываются 16 бит. 15 бит распространяется в старшие. ||
|| || || xx || 1010 || 000000 || xxxxxx || ZF SF || Считывается 32 бита. 31 бит распространяется в старшие. ||
|| || || xx || 1011 || 000000 || xxxxxx || ZF SF || Считывается 64 бита. ||
|| || || xx || 1100 || 000000 || xxxxxx || ZF SF || Старшие биты результата расширяются нулем. ||
|| || || xx || 1101 || 000000 || xxxxxx || ZF SF || *Старшие биты результата расширяются нулем. ||
|| || || xx || 11xx || 000000 || xxxxxx || ZF || Считывается 64 бита. ||
|| wr || 100010 (34) || xx || xxxx || xxxxxx || xxxxxx || -- -- -- -- || Записывается столько бит сколько определено размером типа.||

__wr__::
Поле F1 никогда не может быть равной нулю.
__wr__ в отличии от большинства других команд НЕ возвращают значение операнда (оптимизация выполнения).

h3. === Инструкции работы с регистрами ===

|| || COP || Suffix || TOP || F1 || F2 || Result Flags || Примечание ||
|| || || || || || || || ||
|| exa || 000010 (02) || 01 || 0010 || 000000 || xxxxxx || ZF || Исполнительный адрес, сформированный индексным регистром. ||
|| || || 11 || 0010 || 000000 || xxxxxx || ZF || Исполнительный адрес, сформированный индексным регистром с полем V. ||
|| get || 000011 (03) || xx || 00xx || 000000 || xxxxxx || ZF SF || Значение обрезается до размера типа. Старшие биты нули. ||
|| || || xx || 10xx || 000000 || xxxxxx || ZF SF || Значение обрезается до размера типа. Распространение знакового бита типа. ||
|| || || xx || 1100 || 000000 || xxxxxx || ZF SF || Загрузка значения. Старшие биты нули. ||
|| || || xx || 11xx || 000000 || xxxxxx || ZF || Загрузка значения. ||
|| set || 000100 (04) || 00 || 0011 || xxxxxx || xxxxxx || -- -- -- -- || Пересылка значения коммутатора в регистр. ||
|| || || 01 || 0011 || xxxxxx || xxxxxx || -- -- -- -- || Пересылка значения регистра в регистр. ||
|| || || 10 || 0010 || xxxxxx || 000000 || -- -- -- -- || Запись беззнаковой константы в регистр. Старшие биты нули. ||
|| || || || 1010 || xxxxxx || 000000 || -- -- -- -- || Запись знаковой константы в регистр. Распространение знакового бита типа. ||

__exa__::
В качестве операнда имеет смысл только индексный регистр.

__set__::
Интерпретация значения поля F1 отличается от интерпретации, используемой для других инструкций.
Значением поля F1 является индекс регистра в который записывается значение, сформированное при интерпретации значений поля F2 и/или V.
В отличии от большинства других команд НЕ возвращают значение операнда (оптимизация выполнения).

__get__::
Во всех случаях происходит преобразование типа и/или выставление флагов заново.
При формировании значения аргумента инструкция не обращается к памяти данных.
Формат команды с суффиксом 11 не имеет смысла, т.к. для этого используется __exa__.
Инструкцию можно использовать для преобразования размеров значения целочисленного типа.

Прочтение мнемокода инструкций:
|| exa || EXecutive Address ||

h3. === Арифметические инструкции ===

|| || COP || Suffix || TOP || F1 || F2 || Result Flags || Примечание ||
|| || || || || || || || ||
|| add || 000101 (05) || xx || x0xx || xxxxxx || xxxxxx || ZF SF CF OF || Сложение целочисленное. ||
|| || || xx || 11xx || xxxxxx || xxxxxx || ZF SF OF || Сложение. ||
|| sub || 000110 (06) || xx || x0xx || xxxxxx || xxxxxx || ZF SF CF OF || Вычитание целочисленное. ||
|| || || xx || 11xx || xxxxxx || xxxxxx || ZF SF OF || Вычитание. ||
|| mul || 000111 (07) || xx || x0xx || xxxxxx || xxxxxx || ZF SF CF==OF || Умножение целочисленное. ||
|| || || xx || 11xx || xxxxxx || xxxxxx || ZF SF OF || Умножение. ||
|| adc || 001000 (08) || 00 || 00xx || xxxxxx || xxxxxx || ZF SF CF OF || Сложение с переносом. ||
|| sbb || 001001 (09) || 00 || 00xx || xxxxxx || xxxxxx || ZF SF CF OF || Вычитание с заемом. ||
|| insub || 001010 (10) || xx || x0xx || xxxxxx || xxxxxx || ZF SF CF OF || Обратное вычитание целочисленное. ||
|| || || xx || 11xx || xxxxxx || xxxxxx || ZF SF OF || Обратное вычитание. ||
|| div || 001011 (11) || xx || 1100 || xxxxxx || xxxxxx || ZF SF OF || Деление. ||
|| sqrt || 001100 (12) || xx || 1100 || 000000 || xxxxxx || ZF SF OF || Извлечение квадратного корня. ||
|| max || 001101 (13) || xx || x0xx || xxxxxx || xxxxxx || ZF SF || Выбор наибольшего для целочисленных типов. ||
|| || || xx || 110x || xxxxxx || xxxxxx || ZF SF OF || Выбор наибольшего для float. ||
|| min || 001110 (14) || xx || x0xx || xxxxxx || xxxxxx || ZF SF || Выбор наименьшего. ||
|| || || xx || 110x || xxxxxx || xxxxxx || ZF SF OF || Выбор наименьшего для float. ||
|| abs || 001111 (15) || xx || 1000 || 000000 || xxxxxx || ZF OF || Абсолютное значение знакового байта. ||
|| || || xx || 1010 || 000000 || xxxxxx || ZF OF || Абсолютное значение знакового слова. ||
|| || || xx || 1100 || 000000 || xxxxxx || ZF || Абсолютное значение float. ||

Пояснение:
- Арифметических операций для типов 0011 (unsigned dword), 1011 (dword) не существует.
- Для инструкций в формате AV значение поля V преобразуется к типу операции по правилам для инструкций __set__.
- Поле F1 не может быть нулем, если не оговорено особо.

Инструкции __adc__, __sbb__ используют в качестве операндов арифметической операции значение '''второго''' аргумента и значение флага CF '''первого''' аргумента.

Значения флагов CF и OF вычисляются на разрядной сетке типа инструкции.
Например, флаг сдвига (CF) для байтного сложения выставляется при переносе единицы из 7-ого бита результата в 8-ой.

Для инструкции умножения __mul__ если размер результата получился больше чем размер операнда выставляются оба влага CF и OF.

Прочтение мнемокода инструкций:
|| adc || ADdition with Carry Flag ||
|| sbb || !SuBtract with Barrow (Carry Flag) ||
|| insub || INversion SUBtract ||

h3. === Логические и побитовые инструкции ===

|| || COP || Suffix || TOP || F1 || F2 || Result Flags || Примечание ||
|| || || || || || || || ||
|| or || 010000 (16) || xx || 0011 || xxxxxx || xxxxxx || ZF || Логическое сложение ||
|| and || 010001 (17) || xx || 0011 || xxxxxx || xxxxxx || ZF || Логическое умножение ||
|| xor || 010010 (18) || xx || 0011 || xxxxxx || xxxxxx || ZF || Сложение по mod2 ||
|| not || 010011 (19) || xx || 0011 || 000000 || xxxxxx || ZF || Отрицание ||
|| || || || || || || || ||
|| norm || 010100 (20) || xx || 10xx || 000000 || xxxxxx || ZF || Возвращает значение используемое при нормализации числа с фиксированной точкой. ||
|| pack || 010101 (21) || xx || 0011 || xxxxxx || xxxxxx || ZF || ||
|| patch || 010110 (22) || xx || 0011 || xxxxxx || xxxxxx || ZF || ||
|| || || || || || || || ||
|| sll, sal || 011000 (24) || xx || x0xx || xxxxxx || xxxxxx || ZF SF CF OF || Логический/арифметический сдвиг влево ||
|| slr || 011001 (25) || xx || 00xx || xxxxxx || xxxxxx || ZF SF CF OF || Логический сдвиг вправо ||
|| sar || 011011 (27) || xx || 10xx || xxxxxx || xxxxxx || ZF SF CF OF || Арифметический сдвиг вправо ||
|| rol || 011100 (28) || xx || 00xx || xxxxxx || xxxxxx || ZF SF CF OF || Циклический сдвиг влево ||
|| ror || 011101 (29) || xx || 00xx || xxxxxx || xxxxxx || ZF SF CF OF || Циклический сдвиг вправо ||

'''Примечание''':
COP формата '''011'''xxx зарезервирован для реализации инструкций сдвигов и переходов (см. ниже).

Пояснение:
- Инструкции __or__, __and__, __xor__, __not__ реализованы для внутреннего представления (64 бита).
- Инструкции __shl__ и __sal__ реализованы одинаково, различие в знаковости типа операции можно пренебречь.

Все инструкции сдвига выставляют флаги CF и OF. (Далее используется: MSB - Most Significant Bit).

Флаг CF равен выдвигаемому биту.

Флаг OF определен если сдвиг на один разряд.

SLL, SAL, ROL, ROR::
OF <- 0 if (CF == MSB), т.е. два старших бита операнда были одинаковы.
OF <- 1 if (CF != MSB), т.е. два старших бита операнда были различны.
SAR::
OF <- 0
SLR::
OF <- MSB_первоначального_операнда

Прочтение мнемокода инструкций:
|| sll || Shift Logical Left||
|| slr || Shift Logical Right ||
|| sal || Shift Arithmetic Left ||
|| sar || Shift Arithmetic Right ||
|| rol || ROtate Left ||
|| ror || ROtate Right ||
|| bsr || Bit Scan Reverse ||

h3. === Инструкции передачи управления ===

|| || COP || Suffix || TOP || F1 || F2 || Result Flags || Примечание || Условие перехода || Применимость ||
|| || || || || || || || || ||
|| jmp || 011110 (30) || xx || 0000 || 000000 || xxxxxx || -- -- -- -- || || Безусловный || не значимо ||
|| || || || || || || || || ||
|| je || 011110 (30) || xx || 0001 || xxxxxx || xxxxxx || -- -- -- -- || `V1 == V2` || ZF == 1 || все ||
|| jne || 011110 (30) || xx || 0010 || xxxxxx || xxxxxx || -- -- -- -- || `V1 != V2` || ZF == 0 || все ||
|| js || 011110 (30) || xx || 1000 || xxxxxx || xxxxxx || -- -- -- -- || || SF == 1 || не значимо ||
|| jns || 011110 (30) || xx || 1001 || xxxxxx || xxxxxx || -- -- -- -- || || SF == 0 || не значимо ||
|| jo || 011110 (30) || xx || 1010 || xxxxxx || xxxxxx || -- -- -- -- || || OF == 1 || не значимо ||
|| jno || 011110 (30) || xx || 1011 || xxxxxx || xxxxxx || -- -- -- -- || || OF == 0 || не значимо ||
|| || || || || || || || || ||
|| jb, jc || 011110 (30) || xx || 0100 || xxxxxx || xxxxxx || -- -- -- -- || `U1 < U2` || CF == 1 || без знака ||
|| jbe || 011110 (30) || xx || 0101 || xxxxxx || xxxxxx || -- -- -- -- || `U1 <= U2` || CF == 1 or ZF == 1 || без знака ||
|| ja || 011110 (30) || xx || 0110 || xxxxxx || xxxxxx || -- -- -- -- || `U1 > U2` || CF == 0 and ZF == 0 || без знака ||
|| jae, jnc || 011110 (30) || xx || 0111 || xxxxxx || xxxxxx || -- -- -- -- || `U1 >= U2` || CF == 0 || без знака ||
|| || || || || || || || || ||
|| jl || 011110 (30) || xx || 1100 || xxxxxx || xxxxxx || -- -- -- -- || `S1 < S2` || SF != OF || со знаком ||
|| jle || 011110 (30) || xx || 1101 || xxxxxx || xxxxxx || -- -- -- -- || `S1 <= S2` || SF != OF or ZF == 1 || со знаком ||
|| jg || 011110 (30) || xx || 1110 || xxxxxx || xxxxxx || -- -- -- -- || `S1 > S2` || SF == OF and ZF == 0 || со знаком ||
|| jge || 011110 (30) || xx || 1111 || xxxxxx || xxxxxx || -- -- -- -- || `S1 >= S2` || SF == OF || со знаком ||

Пояснение:

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

Прочтение мнемокода инструкций:
|| je || Jump if Equal ||
|| jne || Jump if Not Equal ||
|| || ||
|| jb || Jump if Below ||
|| jbe || Jump if Below and Equal ||
|| ja || Jump if Above ||
|| jae || Jump if Above and Equal ||
|| || ||
|| jl || Jump if Less ||
|| jle || Jump if Less and Equal ||
|| jg || Jump if Greater ||
|| jge || Jump if Greater and Equal ||

h3. === Инструкции преобразования типов ===

|| || COP || Suffix || TOP || F1 || F2 || Result Flags || Примечание ||
|| || || || || || || || ||
|| cwf || 111000 (56) || xx || 1100 || 000000 || xxxxxx || ZF CF OF || Преобразование word -> float ||
|| cswf || 111010 (58) || xx || 1100 || 000000 || xxxxxx || ZF SF CF OF || Преобразование signed word -> float ||
|| cfsw || 111011 (59) || xx || 1010 || 000000 || xxxxxx || ZF SF CF OF || Преобразование float -> signed word ||

Значения флагов CF, OF необходимо уточнить по признакам, выставляемым алгоритмом преобразования.

Прочтение мнемокода инструкций:
|| cwf || Convert Word to Float ||
|| cswf || Convert Signed Word to Float ||
|| cfsw || Convert Float to Signed Word ||

h3. === Мультимедийные инструкции (MMC MultiMedia Command) ===

Мультимедийные команды выполняются над упакованными значениями.
В данной группе команд TOP может не совпадать с типом результата.

|| || COP || Suffix || TOP || F1 || F2 || Result Flags || Примечание ||
|| || || || || || || || ||
|| madd || 110001 (49) || xx || 1110 || xxxxxx || xxxxxx || ZF SF OF || Упакованное умножение со сложением. ||

'''madd'''::
Для двух упакованных чисел [a,b] [c,d] выполняет операцию: r = a*c + b*d.
Флаги выставляются аналогично инструкции __add__ с типом float.

Прочтение мнемокода инструкций:
|| madd || packed Multiply and ADD ||