beq

beq

RISC-V Ассемблер Ссылка

lyszt.net охватывает beq и другие инструкции RISC-V более подробно.

Формат кодирования

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

Описание

beq позволяет программе принять решение. Процессор обычно выполняет инструкции в том порядке, в котором они появляются в списке. Этот порядок сам по себе не может ничего выбрать или повторить. Ветвление изменяет порядок. Оно проверяет условие, и если условие выполняется, процессор продолжает в другом месте вместо следующей строки. Все операторы if и циклы построены из ветвлений.

Это другое место названо меткой, именем, за которым следует двоеточие, отмечающим позицию в коде, например метка done в примере. beq (branch if equal, ветвление если равно) сравнивает два регистра. Когда они содержат одно и то же значение, оно переходит к помеченной позиции; когда они различаются, выполнение продолжается со следующей инструкцией. Форма показана ниже.

beq rs1, rs2, label

beq только изменяет, какая инструкция выполняется следующей. Сохранение результата да или нет сравнения в виде числа требует другой инструкции, описанной на странице slt.

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

Руководство RISC-V утверждает, что условное ветвление хранит свое смещение как 12-битное значение, отсчитываемое в кратных 2 байтах. Смещение расширяется со знаком и добавляется к адресу инструкции ветвления, давая диапазон плюс или минус 4 KiB, где KiB — это 1024 байта. Инструкции ветвления сравнивают два регистра напрямую и не используют коды условий. Руководство приводит причину, что объединенная инструкция сравнения и ветвления помещается в обычный конвейер и не нуждается в дополнительном состоянии или временном регистре. Оно также советует программному обеспечению держать наиболее распространенный путь как прямой код и ожидать, что обратные ветвления будут предсказаны как выполненные, а прямые ветвления как невыполненные, по крайней мере в первый раз, когда они встречаются.

Ветвление сравнивает два регистра и не может принять константу, записанную в инструкции, поэтому форма вроде beq t0, 5, label не существует. Чтобы сравнить регистр с константой, сначала загрузите константу в регистр с помощью li, затем сравните два регистра.

li t1, 5
beq t0, t1, done

Значение 0 не требует загрузки, потому что регистр zero всегда его содержит.

Обычное использование сравнивает регистр с zero, регистром, который всегда содержит 0, чтобы спросить, достигло ли значение нуля. Это завершает циклы обратного отсчета и проверяет результаты. Пример ветвится к done, когда a0 отсчитало до нуля. beq и метки достаточны, чтобы построить каждое решение и цикл в программе.

Пример

beq a0, zero, done   # if a0 == 0, jump to 'done'