Разница в la и addi для копирования регистра в MIPS asm - PullRequest
1 голос
/ 03 апреля 2020

Я новичок в MIPS и смущен концепцией.

У меня есть значение 5, сохраненное в $s5, и я хочу скопировать его в $a0, чтобы я мог использовать li $v0, 1 для его печати. У меня есть два способа скопировать.

  1. addi $a0, $s5, 0
  2. la $a0, 0($s5)

Либо 1., либо 2. можно напечатать значение 5, если я сделаю li $v0, 1 / syscall после него ( системный вызов печати MARS ).

Но почему он работает для 2.? 2. хранит адрес $s5 в $a0, но нам нужно значение, а не адрес.

Будет ли это автоматически обрабатываться print_integer?

1 Ответ

1 голос
/ 03 апреля 2020

Прежде всего, la - это не аппаратная инструкция MIPS, а просто псевдоинструкция, реализуемая ассемблером, как li. (Обычно с помощью lui / addiu для создания 32-разрядного символьного адреса в регистре, если вы используете его обычным способом, как la $reg, symbol). Посмотрите на разборку / вывод машинного кода, например, как MARS показывает при сборке.

Вы можете использовать la как move, используя режим адресации регистра вместо имени символа. (move - это еще одна псевдоинструкция; MIPS не имеет аппаратного перемещения, вы просто добавляете $zero или 0.)

, который la может собрать в именно это addi $a0, $s5, 0, если ассемблер выбрал это . (Хотя более вероятно, что он выберет addiu; с немедленным, отличным от 0, значение не должно перехватывать переполнение со знаком. В общем случае вы не хотите добавлять / addi, только addu / addiu.)

2 - это хранить адрес $ s5 в $ a0, но нам нужно значение, а не адрес. Будет ли это автоматически обрабатываться print_integer?

Нет, значение в $a0 одинаково в любом случае, как если бы вы сделали move $a0, $s5 как обычный человек. Таким образом, нет разницы в конечном результате для print_integer для сортировки.

Вы не можете взять адрес регистра. Регистр может содержать адрес памяти, но вы не можете взять адрес регистра.

Да la "берет адрес" своего исходного операнда, но учтите, что 0($s5) это не регистр, это синтаксис режима адресации памяти, который ссылается на память по адресу в $s5, как вы можете использовать с lw. Адрес этой памяти просто $s5.

Эквивалент C равен int *a0 = &*s5;, где & отменяет унарное разыменование *.

...