Даже на 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 бит PC новым адресом. (Построен из 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-битных RISC ISA
Пол Клейтон комментирует:
PA-RISC имел «пространственные регистры», которые обеспечивали расширенную адресацию. 32-битный PowerPC имел сегментные регистры, которые выбирались на основе старших 4 битов эффективного адреса из таблицы с 16 элементами (обеспечивая 52-битное виртуальное адресное пространство). Для PA-RISC «SR с 5 по 7 могут быть изменены только кодом, выполняющимся на самом привилегированном уровне». Для PowerPC любой регистр сегмента изменяет требуемую привилегию.
Таким образом, очевидно, что некоторые RISC ISA расширили свою адресацию, прежде чем полностью перейти на 64-битную версию. Но я не знаю подробностей и не планирую тратить время на изучение этого вопроса. Другие ответы приветствуются!
person
Peter Cordes
schedule
07.06.2018
JMP
, так что это означает, что по крайней мере вашPC
является 64-битным, поэтому, возможно, у вас есть 64-битные регистры, где вы можете просто использовать косвенный переход. - person Jester   schedule 07.06.2018JMP
, я думал о чем-то вроде командыJMP
в 8-битном 8080. Она загружает hiAddress (один байт) в один регистр, а loAddress (один байт) в другой. - person Jet Blue   schedule 07.06.2018JMP
) в одно слово (это ключевое отличие между ним и CISC). - person Jet Blue   schedule 08.06.2018