Адресация меток MIPS?
Все это связано, и я постарался собрать все это вместе как можно более логично, поэтому, пожалуйста, потерпите меня.
Я действительно не понимаю, как правильно обращаться с ярлыками. Например, в следующем бите кода "bne" преобразуется в "00010101001001010000000000000001", а адрес метки loopend равен 0x00000020 (32).
.text
la $a0, opOne
lw $a0, 0($a0)
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1
loopend:
Когда я двигаюсь по петле вверх, "bne" становится "00010101001001011111111111111011", а адрес петли становится 0x00000008 (8)
.text
la $a0, opOne
lw $a0, 0($a0)
loopend:
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1
Итак, насколько я понимаю, в первом фрагменте кода loopend
после восьми инструкций, поэтому его адрес 4*8=32=0x00000020. Во втором бите кода, loopend
после двух инструкций, поэтому его адрес 4*2 или 0x00000008.
Однако я не понимаю адрес этикетки. Поправьте меня, если я ошибаюсь: адрес метки зависит от того, где находится метка по отношению к инструкции, вызывающей ее. Итак, в первом фрагменте кода, loopend
на две строки позже, чем bne
так что вы не переворачиваете знаки, а его адрес - "0000000000000001". На втором loopend
приходит раньше bne
поэтому вы переворачиваете знак, и его адрес становится "1111111111111011".
Я знаю, что вы сдвигаете адреса влево на 2 бита, но я все еще в замешательстве. Вы сдвигаетесь только влево, если в конце нет двух нулей, как второй loopend
?
Мой самый актуальный вопрос заключается в следующем: где 0000000000000001, адрес loopend
, даже прийти из первого bne машинного языка перевода? Я думал, что адрес этикетки loopend
будет 0000000000100000.
1 ответ
BNE -- Branch on not equal
___________________________________________________________________________
|Description: | Branches if the two registers are not equal |
|_____________|_____________________________________________________________|
|Operation: | if $s != $t advance_pc (offset << 2)); else advance_pc (4); |
|_____________|_____________________________________________________________|
|Syntax: | bne $s, $t, offset |
|_____________|_____________________________________________________________|
|Encoding: | 0001 01ss ssst tttt iiii iiii iiii iiii |
|_____________|_____________________________________________________________|
Для первого bne смещение равно 1, поэтому 1 << 2 = 4, поэтому вы увеличиваете счетчик программы на четыре байта. Поскольку размер слова составляет 32 бита, компьютер увеличивается на одну инструкцию
.text
la $a0, opOne
lw $a0, 0($a0)
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1 # increment by 1 insruction
loopend: # to here (well the next instruction)
Для второго bne смещение равно b1111111111111011, знак расширил его на -5, поэтому -5 << 2 = -20, так что вы увеличиваете счетчик программы на - 20 байт или уменьшаете его на 20 байт. Поскольку размер слова составляет 32 бита, ПК уменьшается на пять инструкций
.text
la $a0, opOne
lw $a0, 0($a0)
loopend: #
la $a1, opTwo # 5 to here
lw $a1, 0($a1) # 4 ^
add $t0, $zero, $a0 # 3 |
addi $t1, $zero, 1 # 2 |
bne $t1, $a1, loopend # 1 |
addi $t1, $t1, 1 # decrement by 5 instructions