Вырожденные режимы адресации

К этой группе относятся режимы, в которых доступ к операнду не содержит адресации как таковой. Первым из таких режимов является операнд-регистр. Этот режим концептуально крайне прост и в дополнительных комментариях не нуждается. Второй режим — операнд-константа. В документациях по многим процессорам этот режим называют литеральной (literal) и немедленной (immediate) адресацией. Казалось бы, трудно придумать более простой и жизненно необходимый режим. Однако полноценно реализовать такие операнды можно, используя либо команды переменной длины, либо команды, которые длиннее слова. Это чаще всего бывает у процессоров гарвардской архитектуры, например, у уже упоминавшегося PIC.

Литеральная адресация в системе команд SPARC

Разработчики процессоров, которых не устраивает ни одно из названных условий, вынуждены проявлять фантазию. Так, у RISC-процессоров SPARC и команда, и слово имеют одинаковую длину — 32 бита. Адресное поле такой длины в команде невозможно — не остаётся места для кода операции. Выход, предложенный разработчиками архитектуры SPARC, при первом знакомстве производит странное впечатление, но, как говорят в таких случаях, "не критикуйте то, что работает".

Трехадресные команды SPARC могут использовать в качестве операндов три регистра или два регистра и беззнаковую константу длиной 13 бит. Если константа, которую мы хотим использовать в операции, умещается в 13 бит, мы можем просто использовать эту возможность. На случай, если значение не помещается, предусмотрена команда sethi const22, reg, которая имеет 22-разрядное поле и устанавливает старшие биты указанного регистра равными этому полю, а младшие биты — равными нулю.

Таким образом, если мы хотим поместить в регистр 32-разрядную константу value, мы должны делать это с помощью двух команд: sethi %hi (value), reg; or %g0, %lo (value), reg; (в соответствии с [docs.sun.com 806-3774-10], именно так реализована ассемблерная псевдокоманда set value, reg). С точки зрения занимаемой памяти, это ничуть не хуже, чем команда set value, reg, которая тоже должна была бы занимать 64 бита. Зато такое решение позволяет соблюдать принцип: одна команда — одно слово, который облегчает работу логике опережающей выборки команд.

Впрочем, для 64-разрядного SPARC v9 столь элегантного решения найдено не было. Способ формирования произвольного 64-битового значения требует дополнительного регистра и целой программы (пример 2.1). В зависимости от значения константы этот код может подвергаться оптимизации. Легче всего, конечно, дело обстоит, если требуемое значение помещается в 13 бит.

Пример 2.1. Формирование 64-разрядного значения на SPARC v9, цит. по [docs.sun.com 806-3774-10]

! reg — промежуточный регистр, rd — целевой.
sethi %uhi(value), reg
or reg, %ulo(value), reg
sllx reg,32,reg ! сдвиг на 32 бита
sethi %hi(value), rd
or rd, reg, rd
or rd, %lo(value), rd

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

Короткие литералы VAX

У процессоров семейства VAX есть режим адресации, позволяющий использовать битовое поле, которое в других режимах интерпретируется как номер регистра, в качестве 4-битового литерала. Вместе с двумя битами режима адресации этим способом можно задать 6-разрядный литерал, знаковый или беззнаковый в зависимости от контекста. Это позволяет значительно сократить код и повысить его эффективность, особенно в ситуациях, где небольшие значения используются чаще всего.

Короткие литералы МС680хО

У процессоров семейства МС680хО литерал может иметь длину 1 или 2 байта. Кроме того, предоставляются команды ADDQ и SUBQ, которые позволяют добавить к указанному операнду или вычесть из него целое число в диапазоне от 1 до 8. Это расширяет возможности работы с небольшими значениями и позволяет более гибко подходить к выполнению арифметических операций, что также способствует оптимизации кода в процессе выполнения программ.