Похоже, вы путаете машинный код и язык ассемблера.
С точки зрения машинного кода вся инструкция и, следовательно, все ее поля являются просто числами:
- некоторые поля, кодирующие такие вещи, как коды операций,
- некоторые поля, кодирующие такие вещи, как номера регистров, и,
- некоторые поля являются числами, кодирующими такие вещи, как целые числа со знаком или без знака.
Эти кодировки определяются архитектурой набора команд. Аппаратное обеспечение специально разработано для интерпретации этих числовых битовых полей в соответствии со спецификацией ISA.
Ассемблер, компоновщик и загрузчик операционной системы сговариваются, чтобы позволить вам использовать символические значения для формирования инструкций вместо чисел для различных полей (или даже одного числа для всей инструкции):
- мнемоника кода операции для номеров кода операции в полях кода операции,
- имена регистров для номеров регистров в полях регистров и
- метки - даже сложные выражения - для различных непосредственных значений в числовых полях операндов.
Я бы не воспринял слишком серьезно, что один текст будет ссылаться на ra
против rd
. может указывать на несоответствие или просто представлять собой другой способ документирования полей машинного кода инструкции.
Инструкция JAL кодирует два операнда: регистр и непосредственный.
Идентифицированный номер регистра обновляется в соответствии с местоположением адреса возврата, который является местоположением инструкции jal, плюс длина инструкции jal, так что регистр получает значение следующей последовательной (от
адрес) инструкция после jal, которая является правильным обратным адресом при вызове.
Как и все битовые поля в инструкции, непосредственное является кодированием - декодированное значение в конечном итоге дает целевой адрес ветви. Он вычисляется путем преобразования непосредственных битовых полей в смещение со знаком и добавляется к ПК инструкции jal. Кодирование допускает 18 битов (разбросанных по нескольким битовым полям) плюс знаковый бит и не кодирует последний бит смещения (цели ветвления всегда выровнены по 16 битам, что означает, что последний бит всегда будет нулевым, так что это не хранится). В конечном итоге jal может достигать от -0,5 МБ до + 0,5 МБ из самой инструкции jal.
Как упоминалось ранее, исполняющее оборудование преобразует непосредственное (под) поле (поля) в смещение, которое оно добавляет к ПК для определения конечной цели ветвления / вызова. То, что мы можем предоставлять метки и другие сложные выражения на ассемблере, является особенностью этих языков, целью которых является сжатие меток и других выражений в непосредственные константы битовых полей, необходимые процессору для того, чтобы он шел туда, куда и предполагался. Существуют сложные взаимодействия перемещения в объектном коде и / или исправления в загруженном коде, которые гарантируют, что эти непосредственные битовые поля содержат полезную битовую комбинацию, которую аппаратное обеспечение может использовать, основываясь на относительно простом извлечении и добавлении полей во время выполнения, чтобы добраться туда, куда и предполагалось.
Чтобы функции вызывали друг друга, не наступая друг на друга, код ассемблера для вызывающих и вызываемых абонентов должен согласовывать все:
- переданный параметр (ы)
- передан обратный адрес
- возвращаемое возвращаемое значение (я)
- сохраненные регистры
- скретч-регистры
Это широко называется соглашение о вызовах . Это диктует, как звонящий может ничего не знать о вызываемом абоненте и наоборот. Он налагает требования к соглашению о программном обеспечении, для которого регистр или расположение стека содержит первый параметр, второй и т. Д., В котором регистр или расположение стека содержит адрес возврата, как передается возвращаемое значение и какие регистры среды вызывающей стороны сохраняются. по вызову против потенциально стертого по вызову (нуля).
Когда соглашения соблюдаются должным образом, вызывающая сторона (не зная реализации вызываемого, только типы параметров и возвращаемого значения, или сигнатура функции) может
- безопасно хранить локальные переменные в машинных регистрах при вызове,
- передать параметры
- вызовите вызываемого,
- возврат к звонящему,
- , а затем получить возвращаемые значения и продолжить