RISCV - Как инструкции прыжка P C -относительны? - PullRequest
1 голос
/ 20 марта 2020

В RIS C -V Unpriviliged spe c V20191213 указано следующее (стр. 21)

Все инструкции безусловного перехода используют P C -относительную адресацию к помогите поддержать позиционно-независимый код.

Посмотрите на определение инструкции JALR ,

Инструкция косвенного перехода JALR (регистр перехода и ссылки ) использует кодировку I-типа. Целевой адрес получается путем добавления расширенного знака 12-разрядного I-немедленного в регистр rs1, а затем установки наименьшего значащего бита результата равным нулю.

Это вычисление адреса явно не P C -относительно. Итак, почему spe c утверждает, что все инструкции перехода используют P C -относительную адресацию?

Кроме того, как может P C -относительная адресация поддерживать позицию- независимо код? Разве это не должно быть прямо противоположным?

1 Ответ

1 голос
/ 20 марта 2020

Этот расчет адреса явно не является P C -относительным. Итак, почему spe c утверждает, что все инструкции перехода используют P C -относительную адресацию?

Да, вы правы. Вы должны оценить некоторые из различных применений JALR:

  1. для возврата из подпрограммы,
  2. для выполнения косвенных вызовов функций,
  3. для создания большого диапазона (+ / -2GB) вызовы функций

Первые два вообще не требуют какого-либо смещения, поскольку требуемый адрес полностью указан в регистре, поэтому нет необходимости указывать p c -relative.

Последний использует последовательность из 2 инструкций, первая из которых AUIPC, что делает последовательность p c -relative.

Кроме того, как Может ли P C -относительная адресация поддерживать позиционно-независимый код? Разве это не должно быть с точностью до наоборот?

P C Относительно означает, что код может быть загружен в любое место в памяти и все еще будет функционировать - что означает, что код может найти другие части кода независимо от изменения начального адреса, по которому загружается блок кода (или где, если в ПЗУ он появляется в адресном пространстве).

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

(Конечно, независимость позиции не означает, что код может перемещаться один раз выполнение началось! После запуска структуры данных фиксируют адреса кода, поэтому код должен оставаться фиксированным в месте, выбранном для его загрузки, на время выполнения. Независимость от позиции означает независимость от времени загрузки.)

Таким образом, можно захватывать адреса возврата при вызове подпрограммы как прямые / абсолютные значения указателя, которые могут или не могут быть быть сохраненным во фрейм стека, прежде чем использоваться для возврата из подпрограммы, например, используя JALR.

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

(Вы не хотели бы, чтобы операция возврата через JALR была p c -относительной потому что p c адрес JALR в конце возвращаемого вызываемого абонента не имеет отношения к местоположению обратной связи в вызывающем абоненте. Важным является захват адреса возврата относительно JAL, вызвавшего подпрограмму.)


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

  • адрес инструкции вызова вызывающего абонента и адрес первой инструкции вызываемого абонента, который будет будет использоваться как возвращаемое «смещение», которое будет передаваться вызываемому абоненту вместо адреса возврата, и,

  • адрес первой инструкции вызываемый и адрес инструкции вызываемого, который возвращается к вызывающему.

Эти два различия могут быть применены к инструкции относительного возврата ap c во время возврата (например, из p c инструкции возврата). Это обеспечит некоторую степень независимости позиции времени выполнения (например, для обратной связи), но (а) будет слишком сложно, и (б) также будет недостаточно, чтобы сделать все указатели (или использование указателей) позицией времени выполнения независимыми.


Шаг для загрузки / запуска независимого кода:

  1. загрузка кода
  2. перемещение данных
  3. запустите его!

Шаг 2 перемещения может быть исключен, если данные уже знают, куда будет загружен код. В противном случае для перемещения данных в различных местах, где это относится к коду (возможно, нигде), необходимо суммировать базовый адрес загруженного кода с местами данных, которые относятся к коду.

Как только мы пропустим шаг 2 . данные привязаны к коду с использованием абсолютных адресов, и код нельзя перемещать до тех пор, пока выполнение не будет прекращено.

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

...