Каково определение JAL в RISC-V и как его использовать? - PullRequest
0 голосов
/ 29 октября 2018

Я не понимаю, как работает JAL в RISC-V, так как я видел несколько противоречивых определений. Например, если я ссылаюсь на этот сайт: https://rv8.io/isa.html

Это говорит о том, что: JAL rd,offset имеет третий аргумент в качестве смещения, но в некоторых случаях вместо него отображается JAL rd, imm. В чем разница?

Похоже, что JAL должен взять функцию и вернуть свой вывод в rd (что я не знаю, почему некоторые источники называют ее ra и rd одновременно). Но если это так, что такое подпрограмма или функция? rd, кажется, определен как место назначения регистра, а imm, кажется, просто целое число.

Действительно смущен, пожалуйста, помогите.

Ответы [ 2 ]

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

В инструкции jal imm (или imm20) - 20-битное двоичное число.

offset - это интерпретация из imm по инструкции jal: содержимое imm сдвигается влево на 1 позицию, а затем расширяется до размера адреса ( 32 или 64 бита, в настоящее время), что составляет целое число со значением от -1 миллиона (приблизительно) до +1 миллиона.

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

В то же время адрес инструкции, следующей за jal, сохраняется в регистре CPU rd. Вызываемая функция, вероятно, позже использует это для возврата, используя инструкцию jalr rn.

Аппаратное обеспечение RISC-V позволяет любому из 32 целочисленных регистров указывать rd. Если регистр 0 (x0) задан как rd, то обратный адрес отбрасывается, и вы фактически получаете + / 1 МБ goto, а не вызов функции.

Стандартный RISC-V ABI (соглашение о программном обеспечении, не имеющее ничего общего с аппаратным обеспечением) указывает, что для обычных функций rd должен быть регистром 1 (x1), который затем обычно известен как ra (Обратный адрес). Регистр 5 (x5) также обычно используется для специальных функций библиотеки времени выполнения, таких как специальные функции для сохранения и восстановления регистров в начале и в конце функций.

Руководство по набору инструкций RISC-V предполагает, что разработчики ЦП могут выбрать добавление специального аппаратного обеспечения (return address stack), чтобы заставить строго вложенные пары jal x1/x5,offset и `jalr x1 / x5 'работать быстрее, чем можно было бы ожидать Таким образом, может быть преимущество следования стандартному ABI. Однако программа будет работать правильно, даже если используются другие регистры.

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

Похоже, вы путаете машинный код и язык ассемблера.

С точки зрения машинного кода вся инструкция и, следовательно, все ее поля являются просто числами:

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

Эти кодировки определяются архитектурой набора команд. Аппаратное обеспечение специально разработано для интерпретации этих числовых битовых полей в соответствии со спецификацией ISA.

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

  • мнемоника кода операции для номеров кода операции в полях кода операции,
  • имена регистров для номеров регистров в полях регистров и
  • метки - даже сложные выражения - для различных непосредственных значений в числовых полях операндов.

Я бы не воспринял слишком серьезно, что один текст будет ссылаться на ra против rd. может указывать на несоответствие или просто представлять собой другой способ документирования полей машинного кода инструкции.

Инструкция JAL кодирует два операнда: регистр и непосредственный.

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

Как и все битовые поля в инструкции, непосредственное является кодированием - декодированное значение в конечном итоге дает целевой адрес ветви. Он вычисляется путем преобразования непосредственных битовых полей в смещение со знаком и добавляется к ПК инструкции jal. Кодирование допускает 18 битов (разбросанных по нескольким битовым полям) плюс знаковый бит и не кодирует последний бит смещения (цели ветвления всегда выровнены по 16 битам, что означает, что последний бит всегда будет нулевым, так что это не хранится). В конечном итоге jal может достигать от -0,5 МБ до + 0,5 МБ из самой инструкции jal.

Как упоминалось ранее, исполняющее оборудование преобразует непосредственное (под) поле (поля) в смещение, которое оно добавляет к ПК для определения конечной цели ветвления / вызова. То, что мы можем предоставлять метки и другие сложные выражения на ассемблере, является особенностью этих языков, целью которых является сжатие меток и других выражений в непосредственные константы битовых полей, необходимые процессору для того, чтобы он шел туда, куда и предполагался. Существуют сложные взаимодействия перемещения в объектном коде и / или исправления в загруженном коде, которые гарантируют, что эти непосредственные битовые поля содержат полезную битовую комбинацию, которую аппаратное обеспечение может использовать, основываясь на относительно простом извлечении и добавлении полей во время выполнения, чтобы добраться туда, куда и предполагалось.


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

  • переданный параметр (ы)
  • передан обратный адрес
  • возвращаемое возвращаемое значение (я)
  • сохраненные регистры
  • скретч-регистры

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

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

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