Инструкция по сборке bne и br (NIOS II). Как рассчитывается их смещение? - PullRequest
4 голосов
/ 03 октября 2011

У меня есть этот ассемблерный код, который я должен преобразовать в машинный код в двоичном виде:

        .text
        .align 2
        .global main
        .equ val,0x4712         

main:                           
        movi r16,val
        movi r17,0
loop:   addi r17,r17,1
        subi r16,r16,1 
        bne  r16,r0,loop
stop:   br   stop
.end 

и я не уверен, как интерпретируются "bne r16, r0, loop" и "br stop".

Моя ссылка на набор инструкций говорит, что инструкция bne делает это:

if(rA != rB)
then PC ← PC + 4 + σ(IMM16)
else PC ← PC +4

что, насколько я понимаю, счетчик программ увеличивается на 4 + смещение или просто на 4.

Но, в моем случае, каково значение смещения / IMM16? Ссылка на набор инструкций гласит:

"В кодировке инструкций смещение, данное IMM16, обрабатывается как число байтов со знаком относительно инструкции, следующей сразу за bne".

Моя интерпретация этого заключается в том, что значение IMM16 - это «расстояние» до следующего адреса инструкции, но я понятия не имею, верно ли это. Шестнадцатеричный адрес для bne равен 0x40010 и 0x40014 для br, так что это будет означать, что значение IMM16 равно 4? (что привело бы к тому, что ПК перепрыгнул бы адрес 0x40014, если rA! = rB?)

1 Ответ

4 голосов
/ 03 октября 2011

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

если (rA! = RB), то ПК ← ПК + 4 + σ (IMM16), иначе ПК ← ПК + 4

что, насколько я понимаю, счетчик программ увеличивается на 4 + смещение или просто на 4.

Это правильно. Может быть полезно иметь в виду, что ЦП в основном всегда будет делать PC ← PC + 4 после извлечения инструкции для перемещения счетчика программы к следующей инструкции для следующего цикла. Таким образом, даже NOP будет иметь эффективный результат PC +=4 (когда инструкции имеют длину 4 байта). Википедия имеет больше.

Также, поскольку IMM16 может быть отрицательным, вы можете прыгать назад.

Но в моем случае, каково значение смещения / IMM16? Ссылка на набор инструкций гласит:

"В кодировке инструкций смещение, данное IMM16, обрабатывается как число байтов со знаком относительно инструкции, следующей сразу за bne".

Моя интерпретация этого заключается в том, что значение IMM16 - это «расстояние» до следующего адреса инструкции, но я понятия не имею, верно ли это. Шестнадцатеричный адрес для bne равен 0x40010 и 0x40014 для br, так что это будет означать, что значение IMM16 равно 4? (что привело бы к тому, что ПК перепрыгнул бы адрес 0x40014, если rA! = rB?)

Значение IMM16 равно расстоянию, но это расстояние (в байтах) до инструкции, к которой вы хотите перейти в случае rA != rB! Таким образом, в этом случае вы хотите, чтобы непосредственным значением было расстояние от инструкции, следующей за bne (поскольку расстояние относительно следующей инструкции), до места, к которому вы хотите перейти (loop). В этом случае (если мои расчеты верны) address(jump-target) - (address(bne-instruction) + 4) = 0x40008 - (0x40010 + 4) = -12 = ~12 + 1 = 0xfff4 (16-bit).

Поскольку вы беспокоитесь о кодировке инструкций, будьте осторожны и обратите внимание на сигма-функцию, примененную к немедленному. Я сделаю обоснованное предположение и предположу, что оно умножает непосредственное значение на 4, и тогда кодировка команд будет содержать количество инструкций для перехода минус один. То есть -12 байт, вероятно, будут закодированы как 16-битное значение со знаком 0xfffc = -3, так как мы хотим вернуться к двум инструкциям с bne и, таким образом, к 3 инструкциям обратно из инструкции после bne ,

Если это правда, то я до сих пор не понимаю, какое значение имеет значение br в IMM16, поскольку нет следующих инструкций. Может быть, это ноль, когда метка «стоп»? (или к чему приведет bne, если rA! = rB и ПК ← ПК + 4 + σ (IMM16)).

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

...