Адресация меток 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
Другие вопросы по тегам