RISC-V: ПК Абсолют против ПК Относительный - PullRequest
0 голосов
/ 30 сентября 2018

Я новичок в RISC-V.

У меня проблемы с пониманием, когда писать относительные инструкции для ПК (счетчика программ) и когда писать абсолютные инструкции для ПК.

Например,инструкция с lui , за которой следует jalr инструкция считается PC-абсолютной , а инструкция с auipc , за которой следует jalr инструкция считается относительной к ПК .

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

Для меня эти абсолютные инструкции для ПК не будут выполнены.

Может ли кто-нибудь предоставить некоторые базовые примеры, которые помогут мне понять это?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Я думаю, что проблема, с которой вы столкнулись, заключается в концепции «абсолютного ПК», которая на самом деле не вещь.Ваши варианты «ПК относительный» и «абсолютный».RISC-V определяет две инструкции адресации, которые позволяют эффективно реализовать эти режимы:

  • lui (Load Upper Immediate): это устанавливает rd в 32-битное значение с младшими 12 битами0 и старшие 20 битов, поступающие из непосредственного U-типа.
  • auipc (Добавить Upper Immediate to Program Counter): это устанавливает rd в сумму текущего ПК и 32-битногозначение с младшими 12 битами в качестве 0 и старшими 20 битами, поступающими из непосредственного U-типа.

Эти инструкции по сути одинаковы: они оба принимают непосредственный U-тип (т. е. старший20 бит из 32-битного количества), добавьте его к чему-либо и получите результат в rdРазница в том, что lui добавляет это мгновенное значение к 0, а auipc добавляет это немедленное к ПК.Иногда легче представить два режима адресации как «относительный к ПК» и «относительный к 0», поскольку это делает различие более явным.

Хотя оба auipc и lui разработанычтобы работать в качестве первой инструкции в паре из двух инструкций, вторая инструкция не особенно актуальна.И auipc, и lui заполняют старшие 20 бит 32-битного адреса, оставляя инструкцию, с которой они связаны, чтобы заполнить младшие 12 бит.Инструкции в формате I и S спроектированы так, чтобы хорошо сочетаться здесь, и есть вариант I или S каждой инструкции в базовом ISA, для которого такой формат имел бы смысл.

В качестве конкретного примера, следующий Cкод выполняет очень простой

int global;
int func(void) { return global; }

В качестве примера, давайте предположим, что global имеет значение 0x20000004, а ПК первой инструкции в func имеет значение 0x10000008.

При компиляции с -mcmodel=medlow (0-относительный режим адресации), вы получите

func:
    lui a0, 0x20000
    lw  a0, 0x008(a0)

Как видите, полный абсолютный адрес global (0x2000004) заполняется в паре команд.С другой стороны, при компиляции с -mcmodel=medany (режим относительной к ПК) вы получите

func:
    auipc a0, 0x10000
    lw    a0, 0x004(a0)

На этот раз только смещение между ПК auipc и целевым символомпоявляется в паре команд.Это происходит потому, что ПК явно (с помощью инструкции auipc) включен в расчет адресации.В этом случае auipc устанавливает a0 на 0x2000004: вычисление выполняется a0 = PC + (imm20 << 12), и здесь у нас есть 0x10000004 для ПК и 0x10000 для imm20.

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

Для окончательной морщины, как и почти все остальное в ISA RISC-V, немедленные значения, используемые auipc и lui, являются знаками, расширенными до XLEN.В 32-разрядных системах эти режимы адресации могут генерировать любой адрес в системе, но это не относится к 64-разрядным системам.Вот почему мы называем эти режимы адресации «medany» и «medlow»: «med» означает «средний», что означает окно 4 ГБ, в которое должны помещаться все глобальные символы.«Низкая» часть означает, что это окно центрировано вокруг абсолютного адреса 0, в то время как в «любой» части это окно центрировано вокруг любого ПК, с которым он связан.

0 голосов
/ 30 сентября 2018

Относительно ПК
Абсолютно

Вы называете некоторую инструкцию (или код) "Относительно ПК", если адреса рассчитываются относительно адреса самого кода.

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

К сожалению, я не знаю о ЦП RISC V, но в следующем примере для (old) Процессор 68000 показывает, что имеется в виду:

x:
    lea.l (PC+y-x-2), a0
    lea.l (y).l, a0
  ...
y:

Обе инструкции загрузят адрес y в регистр a0.

Однако есть разница:

Предположим, что код расположен по адресу 0x1000, а адрес y расположен по адресу 0x2000.

Теперь мы переместим код по адресу 0x1200 и выполним код там.Что произойдет?

Первая инструкция загрузит адрес 0x2200 в регистр:

Адрес вычисляется относительно к адресу инструкции: Он рассчитывается как(address of the instruction)+0x1000.И поскольку инструкция теперь находится по адресу 0x1000 вместо 0x1200, значение, которое будет записано в регистр, будет 0x2200, а не 0x2000.

Это называется (PC) относительной адресацией .

Вторая инструкция загрузит адрес 0x2000 в регистр.Он всегда загружает значение 0x2000 в регистр - адрес самой инструкции не имеет значения.

Это называется абсолютная адресация .

...