Инструкция по сборке bne и br (NIOS II). Как рассчитывается их смещение?
У меня есть этот ассемблерный код, который я должен преобразовать в машинный код в двоичном виде:
.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 ответ
Отказ от ответственности: я не совсем уверен, что это за набор инструкций, поэтому я постараюсь придерживаться того, что обычно происходит в языках ассемблера.
если (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 и PC ← PC + 4 + σ(IMM16)).
Быть в курсе, что br
может иметь другую кодировку (это может быть, например, абсолютное смещение или другой размер). Я недостаточно знаком с набором инструкций, чтобы знать, но я могу дать общее представление: вы не используете адрес следующей инструкции, скорее вы используете адрес текущей инструкции + 4 (который, если инструкция следует, будет адресом этой инструкции).