Даже на CISC то, что вы описываете, довольно необычно. Это не потому, что CISC, а из-за использования адресов шире, чем регистры .Обычно это встречается только в 8-битных процессорах.(Хотя сегментация x86 также подходит для косвенных прыжков в дальний угол с указателем на пару m16:32
сегмент / смещение. Или в 16-битном режиме, m16:16
. Будучи с прямым порядком байтов, смещение является первым.) Вне 64-битовый режим, jmp ptr16:32
также может кодироваться с абсолютным сегментом: смещение как часть потока команд.)
Обычно, когда вы хотите создать ЦП с большим адресным пространством, вы также делаете регистры более широкими, чтобыВы можете эффективно работать с адресами.Это только на самом низком уровне, когда вы хотите сохранить транзисторы, используя в основном 8-битные регистры / ALU, но не можете ограничить свое адресное пространство 256 байтами, где вы находите этот тип конструкции.
Здесь есть реальная проблема, даже если размер адреса совпадает с размером слова. Построение произвольных 32-битных (или 64-битных) констант является проблемой, которую разные ISA решают по-разному .ARM часто использует относительные нагрузки ПК из соседнего «буквального пула», в то время как другие часто используют lui
или эквивалентный для установки верхних 16 бит и обнуления остальных, затем ori
с 16-битным немедленным.(У ARM есть несколько хитрых приемов для кодирования немедленных кодов с помощью набора нескольких битов с использованием немедленного сдвига / поворота.)
В общем случае в RISC, если вам нужно прыгнуть далеко, вам может понадобитьсячтобы создать адрес в регистре, используя несколько инструкций. Затем используйте инструкцию перехода к регистру.
Инструкции ветви MIPS интересны: у них есть относительные ветви, которые добавляют смещение со знаком к счетчику программы с помощьюдовольно большой диапазон и инструкции абсолютного перехода, которые заменяют младшие 28 бит ПК новым адресом.(Создан из 26-разрядного непосредственного смещения влево, поскольку MIPS требует выравнивания инструкций, чтобы не нужно было хранить младшие 2 бита.) Как вычислить адрес цели перехода и адрес цели ветви? ,Но когда цель не может быть достигнута из текущего местоположения с этими адресами, вам нужно jr
с адресом в регистре.
x86-64 также не хватает 64-битной инструкции относительного перехода.Если вам нужно прыгнуть дальше, чем + -2 ГБ (не far
, как в новом сегменте CS), вам нужен косвенный прыжок.Обычные инструкции перехода / перехода по-прежнему используют смещения rel8
или rel32
, сохраняя машинный код компактным.Единственная инструкция, которая может принять 64-битную немедленную, - это mov
-to-register.Обычная модель кода предполагает, что весь код в одной и той же библиотеке или исполняемом файле находится в пределах 2 ГБ друг от друга, поэтому компоновщик сможет заполнять 32-разрядные смещения.
8-разрядный RISC
Единственный RISC ISA, который мне известен со счетчиком программ, более широким, чем регистры, это AVR, микроконтроллер с 8-битными регистрами. Он может обрабатывать пары регистров как 16-битные адреса , а его ПК - 16-битный.Это IJMP
(косвенный переход) инструкция устанавливает PC = Z (где Z
- пара 8-битных регистров).На AVR с 22-разрядными программными счетчиками вместо 16, это нули PC(21:16)
.
EIJMP (расширенный косвенный переход) берет регистр EIND из пространства ввода / вывода для старших битПК, младшие биты по-прежнему исходят из Z
.
Инструкции AVR имеют длину почти 2 байта, но в некоторых версиях есть 4-байтовая jmp
инструкция , которая занимаетАбсолютный адрес 0..4M для цели перехода.
Основные RISC-машины с 32-разрядными регистрами также имеют 32-разрядные программные счетчики и виртуальные адресные пространства .(Возможно наличие более 4 ГБ физической памяти, но вы не можете отобразить все это одновременно в одном процессе).
Большинство из них в значительной степени ориентированы на слова, поэтому все, что им нужно, - это jr reg
(MIPS) или любой эквивалент, эквивалентный переходу на любой возможный адрес, потому что он помещается в один регистр.Это часть уменьшенной сложности , которую буквально обозначает RISC.
На обычном RISC, таком как MIPS, SPARC или PowerPC, доступны только 64-битные адресав 64-битном расширении ISA , где у вас есть 64-битные целочисленные регистры.Таким образом, вы будете использовать такие инструкции, как MIPS ld $2, 0($3)
, чтобы выполнить 64-битную загрузку (двойное слово), используя $3
в качестве 64-битного базового адреса.См. Руководство MIPS-IV ISA .(MIPS-III добавил 64-битные расширения с такими инструкциями, как ld
и daddu
. Очевидно, MIPS-I оставил большую часть своего пространства кодирования кода операции неиспользованным, поэтому было достаточно места для новых кодов операций, чтобы сделать полные 64-битныеОперации ALU.)
Некоторые 32-разрядные процессоры добавили расширения для поддержки больших физических адресов без увеличения виртуального адресного пространства.Например, PAE x86 определил новый формат таблицы страниц с 36-битными физическими адресами.Но даже при сегментации один процесс не может одновременно обрабатывать более 4 ГБ виртуальной памяти.(основание сегмента x86 + смещение происходит за до перевода virt-> phys, создавая 32-битный линейный адрес. Таким образом, он по-прежнему полезен для локального хранилища потока, например, с [fs:0]
в качестве другого линейного адреса в зависимости отfs
база этого потока.)
Расширенная адресация на 32-битных ISA RISC
Комментарии Пола Клэйтона:
PA-RISC had "космические регистры », обеспечивающие расширенную адресацию.32-битный PowerPC имел сегментные регистры, которые были выбраны на основе наиболее значимых 4 битов эффективного адреса из таблицы с 16 записями (обеспечивая 52-битное виртуальное адресное пространство).Для PA-RISC «SR 5-7 могут быть изменены только кодом, выполняющимся на самом привилегированном уровне».Для PowerPC любой регистр сегмента изменяет требуемую привилегию.
Так что, по-видимому, некоторые ISA RISC действительно расширили свою адресацию, прежде чем полностью перейти на 64-разрядную версию.Но я не знаю деталей и не планирую тратить время на изучение этого вопроса.Другие ответы приветствуются!