Инструкция перехода в сборке MIPS - PullRequest
7 голосов
/ 24 октября 2011

Вот некоторый код сборки MIPS, который я написал для проверки инструкции перехода:

addi $a0, $0, 1
j next
next:
j skip1
add $a0, $a0, $a0
skip1:
j skip2:
add $a0, $a0, $a0
add $a0, $a0, $a0
skip2:
j skip3
loop:
add $a0, $a0, $a0
add $a0, $a0, $a0
add $a0, $a0, $a0
skip3:
j loop

Когда я запускаю ассемблер, вот результат:

[0x000000]  0x20040001  # addi $a0, $zero, 1 ($a0 = 1)
[0x000004]  0x08000002  # j 0x0002 (jump to addr 0x0008)
[0x000008]  0x08000004  # j 0x0004 (jump to addr 0x0010)
[0x00000C]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000010]  0x08000007  # j 0x0007 (jump to addr 0x001C)
[0x000014]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000018]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00001C]  0x0800000B  # j 0x000B (jump to addr 0x002C)
[0x000020]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000024]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000028]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00002C]  0x08000008  # j 0x0008 (jump to addr 0x0020)

Просмотр машинного кодадля инструкций перехода это то, что я вижу:

1st jump (just jumps to next instruction) 0x08000002
2nd jump (skips 1 instruction) 0x08000004
3rd jump (skips 2 instructions) 0x08000007
4th jump (skips 3 instructions) 0x0800000B
5th jump (skips 3 instructions backwards) 0x08000008

Из этих инструкций видно, что машинный код начинается с 08 для инструкции перехода, а число в конце говорит о переходеинструкция куда идти.Однако не могу понять, как рассчитывается это число.Кроме того, мне нечего указывать, что 5-й прыжок - это прыжок назад.

Как рассчитывается значение прыжка?

Ответы [ 2 ]

15 голосов
/ 24 октября 2011

Просто обратитесь к справочному руководству для получения более подробной информации о кодировке кода операции.

Короткая версия: в 32-битной инструкции вы не можете включить 32-битное назначение перехода.Код операции использует 6 битов, что оставляет 26 битов для инструкции.Целевой адрес создается путем взятия первых 4 битов адреса инструкции, следующей за инструкцией j, затем 2 нулевых бита добавляются к 26 битам из операнда инструкции перехода.(Поскольку инструкции являются 32-битными, выравнивание полезно и позволяет пропускать последние два 0.)

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

РЕДАКТИРОВАТЬ : Более подробное описание: У нас есть по адресу x инструкция перехода j .Пусть t представляет операнд скачка j . t имеет ширину 26 бит.Битовая комбинация адреса следующей инструкции вычисляется следующим образом:

upper_6_bits_of(x+4),t,0,0

Таким образом, скачок равен ВСЕГДА абсолют.Там нет относительных прыжков.если результат меньше x, то это прыжок назад, когда он больше, это прыжок вперед (и если вы хотите что-то глупое, вы делаете его равным; -).

Итак, давайте посмотрим на5-й прыжок в вашем примере:

Первые 6 битов цели перехода: 000000, потому что старшие 6 бит адреса инструкции после перехода - 000000.

Следующие 26биты - это самые младшие 26 бит инструкции перехода, то есть 00000000000000000000001000

Последние 2 бита: 00, потому что они всегда добавляются.

Вместе у нас есть: 0000000000000000000000000000100000, то есть шестнадцатеричное 20И по этому адресу находится именно метка / инструкция, где поток должен продолжаться.

6 голосов
/ 24 октября 2011

В MIPS J является инструкцией типа J:

J-type instructions (Jumps)
3    22
1    65                        0
+----+-------------------------+
| op |         target          |
+----+-------------------------+

Итак, у нас есть target длиной 26 бит. Он объединяется с ПК следующей инструкции:

I
I+1 PC <- (PC & 0xf0000000) | (target << 2)

Он сдвинут влево на 2 бита, поскольку инструкции MIPS (без учета расширения MIPS16) имеют длину 32 бита, то есть все они начинаются с адреса, младшие 2 бита которого равны нулю.

...