В чем разница между безусловным переходом и безусловным переходом (инструкции в MIPS)?

Вы можете посмотреть вВикипедия или жекраткое резюме для студентов, Все говорят, что есть две инструкции для одного и того же. Но никто не говорит почему?

 phuclv11 мар. 2018 г., 02:18
первое различие заключается в формате: один тип-R и один тип-J

Ответы на вопрос(4)

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

Возьми этот пример

b l0
nop
beq $0,$1,l1
nop
j l2
nop

l0: .word 0,0
l1: .word 0,0
l2: .word 0,0

и вы получите это

00000000 <l0-0x1c>:
   0:   10000006    b   1c <l0>
   4:   00000000    nop
   8:   10010006    beq zero,at,24 <l1>
   c:   00000000    nop
  10:   0800000b    j   2c <l2>
  14:   00000000    nop
  18:   00000000    nop

0000001c <l0>:
    ...

00000024 <l1>:
    ...

0000002c <l2>:
    ...

Теперь, что другие ответы, возможно, не упомянули, это то, что безусловныйbranch кодируется, по крайней мере ассемблером GNU, как ветвь, если она равна, с тем же регистром. В mips нет безусловной ветви, есть ветвь, если она равна, и ветвь, если она не равна, что я могу сказать.

Вы видите выше, переход использует 0xB, который является адресом слова, 0xB * 4 = 0x2C адрес получателя, где условные выражения используют относительную адресацию pc + (signature_offset * 4), где pc = инструкция_адрес + 4; Или возьмите инструкцию_адрес + 4 + (подписано_смещение * 4), чтобы получить адрес назначения.

Использование псевдонима b для перехода вместо j для перехода создаст независимый от позиции код. Прыгать не нужно, придется пересвязывать при перемещении, для ближних прыжков, вероятно, лучше использовать переход вместо прыжка, даже если это псевдоним. Если вы пурист, то вы можете использовать реальную инструкцию beq $ 0, $ 0, обозначить или выбрать любой регистр beq $ 4, $ 4, обозначить. регистр 0, являющийся особенным и быстрым, может быть лучшим выбором.

 11 июн. 2012 г., 17:27
это может вызвать остановку или блокировку, добавить r1, r2, что-то; beq r1, r1, где-то может выполняться по-другому, потому что он может или не может дождаться, пока предыдущая инструкция завершит выполнение и обратную запись, чем добавить r1, r2, что-то; beq r0, r0, где-то как r0 никогда не пишется. Просто зависит от ядра и т. Д. Изолированные да, один регистр так же хорош, как другой для целей скорости чтения.
 Val11 июн. 2012 г., 17:16
Благодарю. Мы знаем, что ветвь является псевдоинструкцией. Мне нравится, что ваша попытка намека при использовании одной инструкции может быть предпочтительнее другой. Но я думаю, что скорость доступа одинакова для всех регистров (потому что процессор синхронный)

b) использовать относительное смещение ПК во время прыжков (j) использовать абсолютные адреса. Различие важно для позиционно-независимого кода. Кроме того, только косвенные переходы могут использоваться для косвенной передачи управления (jr, используя значение регистра).

 10 мар. 2018 г., 23:54
Чтобы быть точным, все инструкции перехода и ветвления, кромеjr использовать смещения в машинном коде.
Решение Вопроса

трукции. Следовательно, адрес ветвления составляет всего 2 ^ 16 битов и позволяет только ветвить 2 ^ 15 - 1 инструкций назад или 2 ^ 15 инструкций вперед.

Прыжок является безусловным, и биты, сохраненные при исключении условия, могут быть использованы для адреса. Переход допускает 26-битный адрес и поэтому может перейти намного дальше в коде, чем ветвь. За счет не быть условным.

 12 февр. 2015 г., 03:53
Это не решает вопрос о том, есть ли разница между безусловным переходом и безусловным переходом.
 07 мая 2014 г., 12:49
Итак, если я не заинтересован в состоянии, прыжок всегда лучше?
 11 июн. 2012 г., 16:18
Обратите внимание, что это может быть верно для MIPS, но не для всей мнемоники процессора. Z80 имеет относительные переходы, и условные переходы, и условные относительные переходы. Ветвь - это слово, отсутствующее в сборке Z80.
 07 мая 2014 г., 15:41
@HelloWorld Обычно? Да. Но всегда? Нет. Одна ситуация, о которой я могу подумать, - это устройство с очень маленькой памятью. В этом случае вам не нужно далеко ходить и вы хотите сохранить как можно больше битов. Таким образом, безусловная ветвь была бы более подходящей.

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

Они отличаются тем, что ветви являются условными, они изменяют только следующую команду, которая будет выполнена, если выполнено определенное условие. Это может быть проиллюстрировано различием в коде выполнения вif заявление или вызов функции.

if (a == 0) {
    a = 1
}
setAtoOne()

if оператор переходит к инструкции для установкиa = 1 только еслиa == 0, Функция перейдет к этой инструкции независимо.

В этом случае мы говорим о ветви, в которой условие всегда выполнено. Это просто еще один способ написания

beq $zero, $zero, (int)offset

$ ноль всегда равен $ ноль, поэтому он всегда переходит к указанному смещению. Это как выражение if

if (true) { a = 1 }

Существует еще одно различие между инструкциями перехода и перехода. Инструкции перехода указывают абсолютный адрес, по которому будет установлен ПК, а инструкции перехода компенсируют адрес в программном счетчике.

PC = 32-bit address # Jump
PC += 16-bits lower

На самом деле это не совсем так. Мы пишем сборку с абсолютными адресами и смещениями, но как в переходах, так и в ветвях она компилируется в смещение. Вот почему вы не можете переходить или переходить в любое место в памяти, ожидайте использовать переход для регистрации.jr инструкция. Это из-за фундаментального дизайна MIPS, инструкции фиксированной длины одним словом.

Все инструкции MIPS имеют длину 1 слово (т.е. 4 байта / 32 бита). Они содержат идентификатор для инструкции (называемый операционным кодом), который составляет 6 битов вместе с другой информацией, необходимой для выполнения инструкции. Это может быть идентификатор регистров или «немедленный»; значения, в основном целые числа, закодированные в инструкции.

Каждый байт в памяти в MIPS имеет адрес между0x00000000 - 0xFFFFFFFF, Чтобы добраться до одного из этих байтов, нам нужно указать адрес. Если бы нам удалось сохранить адрес в реестре, мы бы простоjr и использовать адрес, уже сохраненный в реестре. Тем не менее, мы не.

Это становится проблематичным, у нас есть только 32 бита для наших инструкций, и нам нужны все эти биты для указания адреса в этом диапазоне. Нам также пришлось отказаться от 6 битов, которые будут использоваться процессором для идентификации инструкции. Теперь у нас осталось 26 бит.

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

Допустим, мы находимся по адресу0x12345678 и мы выполняем безусловный переход к следующему адресу в памятиj 0x1234567c, Это код ассемблера, и я покажу, как он переводится в машинный код и выполняется.

Сначала мы немного обманываем. Мы знаем, что инструкции состоят из одного слова (4 байта), и в MIPS указано, что они должны находиться в пределах границы слова. Это означает, что все инструкции имеют адреса, которые находятся на расстоянии 4 байта, и это означает, что они всегда заканчиваются на 00 в двоичном представлении. Отлично, мы можем сбрить эти две бессмысленные части. Мы также бреем первые 6, но не волнуйтесь, мы вернем их позже.

jump <strong>0001 0010 0011 0100 0101 0110 0111 11</strong><s>00</s>
jump <s>0001</s> <strong>0010 0011 0100 0101 0110 0111 11</strong><s>00</s>
<i>0000 10</i><strong>00 1000 1101 0001 0101 1001 1111</strong> #in machine code # jump op = 0000 10
Когда мы выполняем это, мы берем
00 1000 1101 0001 0101 1001 1111
0000 00<strong>00 1000 1101 0001 0101 1001 1111</strong>  # extend >> 6
0000 00<strong>10 0011 0100 0101 0110 0111 11</strong>00  # << 2 
Затем мы И ПК (с которого мы выполняем) и 0xf0000000

0001 0010 0011 0100 0101 0110 0111 1000
1111 0000 0000 0000 0000 0000 0000 0000
AND
0001 0000 0000 0000 0000 0000 0000 0000

Мы знаем, взять результат этого и ИЛИ его с нашей инструкцией integer

0001 0000 0000 0000 0000 0000 0000 0000
0000 0010 0011 0100 0101 0110 0111 1100
OR
0001 0010 0011 0100 0101 0110 0111 1100

Который0x1234567c в Hex и куда мы хотим идти, теперь мы прыгаем туда. Вот почему вы не можете перейти дальше 256 МБ (2 ^ 28 бит) от вашей текущей инструкции (если вы не перейдете к значению регистра).jr)

Та же самая базовая идея применима к ветвям, за исключением того, что теперь у вас также есть сравниваемые 2 регистра (которые требуют 10 бит), поэтому у вас есть только 16 бит, которые вы можете использовать для смещения, поэтому вы не можете прыгать так далеко с ветвями.

Как правило, это нормально, потому что мы в основном используем ветки в процедуре для реализации циклов и выполнения условных присваиваний.

Все это является следствием дизайна архитектуры MIPS. Было бы вполне возможно иметь инструкции, в которых единственным различием между ветвями и переходами были бы условные аспекты и где «безусловный»; Ветвь вела бы себя так же, как безусловный прыжок.

Ваш ответ на вопрос