Машинный код для ветвления

Я немного смущен тем, как инструкция ветвления переводится в машинный код. Я прочитал в своей книге, что ветвь, если инструкция равна, является инструкцией типа B, которая отформатирована следующим образом:

код операции reg1 reg2 адрес + смещение 6 5 5 16

В моем учебнике есть проблема, когда мне показывают программу, которая, как мне сказали, загружается по адресу 0x4321ABC8 и выглядит так:

L1:   sw   $t0,3000($t1)

  addi $s1,$t1,-6

  beq  $t0,$t1,L1

Как видите, третья строка кода является ветвью, если она равна.

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

Сначала я думал, что ответ будет...

базовый адрес (0x4321ABC8), плюс 4-кратное количество инструкций из базы, где должен быть счетчик команд (4 * 2 = 8),
Затем минус четыре для смещения, которое будет исходным базовым адресом, 0x4321ABC8 .

Проблема в том, что 0x4321ABC8 — слишком большое число, чтобы поместиться в 16-битное смещение инструкции.

Итак, я подумал, что ответ будет ТОЛЬКО включать смещение (которое будет -8), однако, если бы это было так, я не знаю, почему проблема в книге удосужилась сообщить мне, что программа загружена по адресу 0x4321ABC8.

Любая помощь будет принята с благодарностью!


person SemperCallide    schedule 28.02.2014    source источник


Ответы (1)


Смещение на самом деле кодируется как количество слов (или инструкций, если хотите), поэтому вам не нужно умножать на размер слова (4 байта). Кроме того, это смещение относительно уже обновленного PC, то есть адреса следующей инструкции. Итак, ваше смещение равно -3.

Это еще не вся история. MIPS имеет слоты задержки ветвления, но обычно они скрыты от программиста. Ассемблер может попытаться заполнить их, если он может сделать это без изменения смысла вашего кода. Если вы передадите свой пример реальному ассемблеру (в данном случае gas), он переместит addi $s1,$t1,-6 в слот задержки ветки, потому что результат этой инструкции не используется в условии:

00000000 <L1>:
   0:   ad280bb8        sw      t0,3000(t1)
   4:   1109fffe        beq     t0,t1,0 <L1>
   8:   2131fffa        addi    s1,t1,-6

В этом переставленном порядке закодированное смещение равно -2, как вы также можете видеть из значения fffe.

PS: Если вы используете SPIM, имейте в виду, что у него есть известная проблема с несовпадением единиц при кодировании смещения. То есть он использует адрес текущей инструкции вместо следующей.

PS № 2: То, что они дают вам дополнительную информацию, не означает, что вы должны ее использовать. Это обычная уловка, чтобы запутать бедных студентов;)

person Jester    schedule 28.02.2014
comment
Итак, пожалуйста, простите меня, пока я уточняю, значение, которое будет идти в 16-битной части операции смещения, будет -3? Что будет (в двоичном формате) 1111 1111 1111 1101? - person SemperCallide; 28.02.2014