Страница произведения
Войти
Зарегистрироваться
Страница произведения

О системах команд (пишется)


Автор:
Жанр:
Детская
Опубликован:
26.07.2015 — 13.11.2017
Читателей:
1
Аннотация:
приложение к главе 7 книги о Фокале: пока только про систему команд PDP-11 и MSP-430 (ред.2.1 от 13.11.16 - добавил: расширенный режим МСП-430)
Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава
 
 

А<=Б -> C=1 результат получится "отрицательный" — перенос выскочит

за пределы разрядной сетки

для чисел со знаком дело обстоит сложнее:

А>Б определяется по комбинации признаков N^V (здесь ^ — искл.ИЛИ)

а для А<=Б эта комбинация должна быть равна нулю (т.е. либо оба нули, либо

оба единички)

Команд ветвления, использующих эти признаки результата — восемь. Устроены

они так: младший байт — расстояние на которое надо перейти, если проверяемое

командой условие выполняется — однобайтовое число (со знаком), указывающее

количество слов, т.е. прибавляющееся к счетчику команд со сдвигом на один бит.

Один бит — состояние проверяемого признака, при котором надо переходить,

остальное — код операции (КОП).

К0КSSS по битам: К 000 кКК ПSS SSS SSS где S — смещение, П — признак, К — КОП.

0 04 BR 0 000 1 — "безусловный" переход — ничего не проверяет

0 1 BNE / BEQ 0 001 * — Z если равно / не равно (нулю)

0 2 BGE / BLT 0 010 * — N^V >=0 / <0 — для чисел со знаком

0 3 BGT / BLE 0 011 * — Z|(N^V) >0 / <=0 — для чисел со знаком

1 0 BPL / BMI 1 000 * — N если плюс / минус

1 1 BHI / BLOS 1 001 * — C&Z >0 / <=0 — для чисел без знака

1 2 BVC / BVS 1 010 * — V нету переполнения / есть

1 3 BCC / BCS 1 011 * — C нету переноса / есть

или BHIS / BLO — C >=0 / <0 — для чисел без знака

Здесь команды перечислены в порядке возрастания кодов операций (а не в

логическом порядке — типа сначала проверка отдельных признаков, потом их

комбинаций для сравнения чисел со знаком и без такового). Обратим внимание: один

бит кода операции (тот, который обозначен маленькой буквой к) неизменно ноль, зато

вместо него задействован старший (знаковый) бит слова. Это к тому, как шло

распределение пространства кодов команд.

r ккк xxx xxx yyy yyy — двухадресная команда — кроме ккк = 000 и 111

из того, что осталось:

1 111


* * *


* * *

* * — зарезервировано под команды ППЗ

к 000 0кк пss sss sss — команды ветвления К0К


* * *

(кроме к_ккп = 0_000)

* 000 1кк ккк ххх ххх — одноадресные команды, из них мы уже рассмотрели:

r ... .01 ккк ... ... — основные *05К**

r ... .10 0кк ... ... — команды сдвига *06К** (только 4 штуки)

значит пока что незадействованными (или нерассмотренными) остались коды:

* ... .10 1** — 4 штуки *064** — *067**

* ... .11


* * *

— 8 штук *07


* * *

еще пропущена команда с кодом 00 (с учетом старшего бита — 2 штуки)

* ... .00 ... ... ... *04


* * *

это будут JSR и EMT/TRAP

ну и совершенно еще не использованные

0 111


* * *


* * *

* * 07


* * *

а так же — то, что осталось от команд ветвления (к_ккп = 0_000)

0 000 000 0*


* * *

* * — т.е. команды с полностью нулевым старшим байтом

А ведь у нас еще совершенно не рассмотрены команды передачи управления.

Четыре блудных команды вида *064** — *067** (с учетом использования под код

операции знакового разряда — 8 штук) я всётаки насобирал как говорится "с бору

по сосенке":

— Команда SXT с кодом 0067ХХ (где ХХ — полноформатный операнд) — "расширение

знака" — заполнение старшего байта слова знаковым разрядом младшего. Т.е.

превращение однобайтового целого числа в двухбайтовое. (Кстати, при загрузке

байта в регистр это происходит автоматически.)

— Пара команд с кодами 1067ХХ и 1064ХХ — MTPS и MFPS — загрузка операнда ХХ в

слово состояния процессора и наоборот — сохранение ССП по указанному адресу.

У старших моделей они отсутствуют, т.к. это была бы "дырка" в механизме защиты.

(Вместо этого есть привилегированная команда SPL для установки уровня приоритета

и обычная команда с кучей разных названий для установки и сброса признаков

результата, имевшаяся впрочем и самых младших моделей.)

— За то у самой старшей модели (где всё по максимуму) есть четыре интересные

команды с кодами 0065ХХ, 1065ХХ, 0066ХХ и 1066ХХ — MFPI, MFPD, MTPI, MTPD,

занимающиеся пересылкой слова данных ХХ из предыдущего адресного пространства

на стэк текущего. И соответственно со стэка в. А две пары потому что адресные

пространства команд и данных там видите-ли раздельные. (Можно сделать, но не

обязательно. Впрочем речь об этом еще впереди.)

— И еще одна заблудившаяся команда MARK с кодом 0064NN, делающая что-то очень

хитрое. Впринципе это возврат из подпрограммы с параметрами (с одновременным

истреблением оных). Вот сейчас мы это и рассмотрим.

Впринципе для передачи управления в любую точку оперативной памяти (а не на

+/-127 слов как у команд ветвления) вполне хватило-бы команды пересылки MOV:

записал адрес точки перехода прямо в регистр R7 и всё. (В идейном потомке PDP-11

микроконтроллере MSP-430 так и сделано.) Эта возможность не исключается и здесь.

Но разработчики архитектуры сделали отдельную команду JMP с кодом 0001АА, в

которой АА, в отличии от команды MOV с кодом 01АА07 не указание того места, где

взять адрес по коему надо перейти (засунув его в R7), а того, где следующая

подлежащая выполнению команда. (Но если АА = 0х, то получается что эта команда

— в регистре Rх, что абсурд. Зачем так сделано — не знаю, разве что по аналогии

с командой передачи управления подпрограмме JSR.

Команда передачи управления подпрограмме JSR — полутораадресная. Её код

004RАА включает так же как и код команды JMP, указание куда передать управление,

а кроме того — номер регистра, где сохранить адрес возврата. Содержимое самого

этого регистра сохраняется на стэке. А командой возврата из подпрограммы RST с

кодом 00020R — восстанавливается обратно. Спрашивается, зачем так сложно? Почему

нельзя, как все люди, сразу сохранить адрес возврата на стэке, уж коли он есть?

(Впрочем, если в качестве этого регистра указать сам счетчик команд — так оно и

происходит.) Это ведь когда стэка еще небыло — адрес возврата вот так сохраняли

в регистре, а сейчас-то зачем? А это даёт дополнительную гибкость. Например

сразу после команды вызова подпрограммы можно поместить некую полезную

информацию для неё (ну хотя бы текстовую строку, которую оная программа должна

вывести на терминал в качестве диагностического сообщения). Теперь ей не надо

выковыривать из стэка адрес где это находится — он уже в регистре;

попользовалась, сдвинув оный регистр-указатель на первое слово после этой,

предназначенной ей информации — там как раз и будет следующая команда, которой

надо возвернуть управление. Очень удобно.

Уже упоминавшаяся хитрая команда MARK с кодом 0064NN служит для "маркировки"

конца списка параметров и/или локальных переменных подпрограммы (NN штук)

завалявшихся на стэке и при возврате из оной подпрограммы подлежащих удалению.

Она помещается на вершину стэка самой подпрограммой, которая обязательно должна

получать управление командой JSR R5, AAAA; и которая для возврата управления

должна употребить команду RST R6. Тогда R7 <— R6, а там как раз и лежит вот эта

самая команда MARK NN, она делает: R6 <— R7+NN*2; R7 <— R5; R5 <— (R6)+.

Еще к командам передачи управления относятся "командные прерывания"

предназначенные прежде всего для обращения к операционной системе (за услугами)

или каким другим системным программам (например к отладчику или некоему

супервизору ввода/вывода). Не в пример писишке каждой из таких команд поставлен

в соответствие один единственный фиксированный вектор прерывания. Который ни при

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

четыре: EMT и TRAP с кодом 104ХХХ отличаются одним битом (младшим во втором

байте), а весь младший байт отведён под код запроса — на выполнение команды он

никак не влияет. (То есть получившая прерывание системная программа должна

слазить в то место, куда указывает адрес возврата, взять младший байт команды и

отработать ту функцию, на которую он намекает.) Не знаю почему их две — наверно

просто так коды распределились. Однако одни операционные системы (например

RT-11) используют EMT, а другие (например UNIX) — TRAP. Может у кого-то была

мысль сделать под UNIX`ом виртуальную RT-11? Их вектора 030 и 034.

Два других командных прерывания BPT и IOT с векторами 014 и 020 и кодами

00003 и 00004 якобы предназначены для отладчика и подсистемы ввода/вывода.

(Ну типа отладчик организует в отлаживаемой программе точку останова подменяя

одну из её команд на BPT, а как получит по ней управление — незаметно подменяет

её обратно. Ну а с вводом/выводом-то как?)

Следует иметь в виду, что при прерывании в стэке сохраняется не только

счетчик команд, но и слово состояния процессора. А новые загружаются из вектора

прерывания. (Потому-то они и идут через четыре байта — эти самые четыре байта и

загружаются.) Следовательно и возврат из прерывания должен производиться не как

из подпрограммы, а специально на то предназначенной командой. Каковых две:

000002 RTI — просто возврат из прерывания — без всяких затей

000006 RTT — хитрый возврат из прерывания — специально для отладчика

Тут дело вот в чём: в слове состояния процессора есть такой специальный

признак Т. Если он равен нулю — всё как у людей. А вот если его установить в

единицу — сразу же будет прерывание по тому же самому вектору 014 что и по

команде BPT. А установиться в единицу он может например по команде возврата из

прерывания (ну вот такое слово попало в ССП из стэка). А отладчику, желающему

прогнать программу по шагам, надо чтобы не сразу, а только после того, как

выполнится одна команда. Вот для этого он RTT и использует.

Еще к командам управления можно отнести следующие:

000000 HALT — стоп — останавливает процессор (привилегированная!)

000001 WAIT — ждать — висит на этой команде пока не произойдёт прерывание

000005 RESET — сброс — сброс всех внешних устройств в некое исходное

состояние — в старших моделях ясный пень тоже привилегированная, потому как

приводит в состояние изумления не только всякие там принтеры с терминалами (ну

или контроллеры дисководов, ежели они есть), но и такую важную штуку, как

диспетчер памяти. И буде учинить её в защищенном режиме — одному Аллаху известно

к чему это приведёт.

Еще есть такая привилегированная команда SPL с кодом 00023N -

устанавливающая уровень приоритета прерываний N (буде командами MTPS / MFPS

напрямую читающей и пишущей обратно целиком всё слово состояния процессора

воспользоваться нельзя). И всё — кроме этих трёх других "привилегированных"

команд даже в самой старшей модели нет. (А привилегированность их заключается в

том, что в "системном" режиме они успешно выполняются, а в "пользовательском" -

нет — вызывают прерывание. По-моему по вектору 010, по которому вообще

происходит прерывание при попытке выполнить неизвестную данному процессору

команду.)

Ну про что я еще забыл, прежде чем перейти к "расширенным" командам? Ну

конешно про сброс и установку наших любимых признаков NZVC! Команда эта с кодом

00024Х точнее по битам: 0 000 000 010 1yX XXX где y указывает что именно

нужно сделать — установить указанные единичками в битах ХХХХ признаки NZVC (вот

именно в таком порядке), или же наоборот сбросить. Названий у этой команды -

пруд пруди, в том числе NOP (ничего не делать) — это если все ХХХХ нулевые.

000240 NOP 000260 NOP ничего не делать

000241 CLC 000261 SEC сбросить/установить признак C

000242 CLV 000262 SEV -//— V

000244 CLZ 000264 SEZ -//— Z

000250 CLN 000270 SEN -//— N

000257 CCC 000277 SCC сбросить/установить всё

Ну и еще команда SWAB с кодом 0003АА — перестановка байтов в слове. Она вроде

бы тоже не расширенная а из основного набора.

Подводя промежуточный итог, отметим, что базовый набор команд это

необходимый минимум. Он позволяет выполнить любые требуемые действия, но

содержит только самые элементарные операции. Ни умножения с делением ни тем

более операций с плавающей запятой там нет. Их придётся эмулировать.

"Расширенные" команды — полутораадресные: здесь почти все команды (кроме

исключающего ИЛИ, ну и возможно одинарного многобитного сдвига, которые надо бы

включить в основной набор двухадресных команд, да вот к сожалению элементарно

кодов не хватило) используют пару соседних регистров (обозначено R и R'),

отличающихся младшим битом номера. (Т.е. если указан R2, то второй конешно же

будет R3, а вот если указан R3, то R' будет вовсе не R4, а R2!)

070RАА MUL — целочисленное умножение R*A -> (R,R')

071RАА DIV — целочисленное деление (R,R') / A -> R, R' (остаток)

072RАА ASH — арифметический сдвиг на несколько разрядов (6 бит операнда А)

073RАА ASHC — сдвиг на несколько разрядов двух регистров R и R'

074RАА XOR — исключающее ИЛИ (инверсия битов) R^A -> A

Стэковая плавающая арифметика одинарной точности

07500R FADD — сложение

07501R FSUB — вычитание

07502R FMUL — умножение

07503R FDIV — деление

Регистр R — указатель вершины операционного стэка, с которого берутся

(черырёхбайтовые в данном случае) операнды и куда кладётся результат. Как видим,

здесь свободных кодов — полным-полно (еще 60 штук: 07504R — 07577R) — вполне

хватит соорудить полноценный стэковый сопроцессор. Но в эту сторону развитие

архитектуры не пошло. А с реализацией ППЗ и эти команды упразднили.

Команды вида 076ХХХ тоже нигде не задействованы.

077RNN SOB — цикл со счетчиком: счетчик (регистр R) уменьшается на единицу,

и если получился не ноль — производится переход назад на NN слов.

Вот собственно и вся система команд.

Ах да, еще кажется у Э-85 завалялась такая команда MFPT с кодом 000007,

записывающая в R0 некую константу, содержащую код модели процессора в младшем

байте и что-то такое еще — в старшем. Уж и не знаю зачем.

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

вещи и по-интереснее. Диспетчер памяти например. И вообще структура памяти.

Ну что можно сказать про память? Адресное пространство — линейное (или

"плоское"). Размер адреса равен разрядности процессора и размеру машинного

слова. Причём в виду наличия развитой системы косвенной адресации это

принципиально. То есть увеличить размер адреса в пределах данной архитектуры

невозможно — для этого надо делать другую машину с другой системой команд.

(Что и было сделано: VAX-11.) Впрочем на момент разработки (и следующие десять

лет) объём адресного пространства в 2^16 байт казался прямо-таки необъятным!

Оперативной памяти туда устанавливалось куда как меньше. Но как известно, дашь

коту сала, а ему всё ма-а-ало! И в конце-концов настали времена...

Впрочем еще раньше появились "старшие" модели, заточенные под многозадачный

Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава



Иные расы и виды существ 11 списков
Ангелы (Произведений: 91)
Оборотни (Произведений: 181)
Орки, гоблины, гномы, назгулы, тролли (Произведений: 41)
Эльфы, эльфы-полукровки, дроу (Произведений: 230)
Привидения, призраки, полтергейсты, духи (Произведений: 74)
Боги, полубоги, божественные сущности (Произведений: 165)
Вампиры (Произведений: 241)
Демоны (Произведений: 265)
Драконы (Произведений: 164)
Особенная раса, вид (созданные автором) (Произведений: 122)
Редкие расы (но не авторские) (Произведений: 107)
Профессии, занятия, стили жизни 8 списков
Внутренний мир человека. Мысли и жизнь 4 списка
Миры фэнтези и фантастики: каноны, апокрифы, смешение жанров 7 списков
О взаимоотношениях 7 списков
Герои 13 списков
Земля 6 списков
Альтернативная история (Произведений: 213)
Аномальные зоны (Произведений: 73)
Городские истории (Произведений: 306)
Исторические фантазии (Произведений: 98)
Постапокалиптика (Произведений: 104)
Стилизации и этнические мотивы (Произведений: 130)
Попадалово 5 списков
Противостояние 9 списков
О чувствах 3 списка
Следующее поколение 4 списка
Детское фэнтези (Произведений: 39)
Для самых маленьких (Произведений: 34)
О животных (Произведений: 48)
Поучительные сказки, притчи (Произведений: 82)
Закрыть
Закрыть
Закрыть
↑ Вверх