This page covers if conditional statements in RISC-V.
In higher-level programming languages, an if-statement looks similar to the following:
if (condition) {
code statement(s)
}
In assembly, simple condition
expressions are computed by a branch instruction.
A branch instruction does a boolean comparison of the value in two registers
(==, >, <=, etc) and either executes the instruction immediately after the branch
instruction, or jumps to a specified label and continues from there.
When converting a higher level code into assembly, it is common for the conditions in
the branch conditions to be the opposite of the conditions in the higher level code.
Consider the following C
code:
if (x == 0) {
a = b + c;
}
a = b - c;
This code can be converted into assembly this way:
# Same order as original code
bne t0, zero, _after # if x != 0 goto _after
add t1, t2, t3 # a = b + c;
_after:
sub t1, t2, t3 # a = b - c;
This assembly assumes that x
is in register t0
, a
in t1
, b
in t2
, and
c
in t3
. To maintain the order of the statements in the original C code, the
instruction used for the branch is bne
, which stands for "branch not equal".
The condition is true if x
is not equal 0
.
An alternative conversion of the C code into assembly is this way:
# Same condition expression as original code
beq t0, zero, _add # if x == 0 goto _add
j _after
_add:
add t1, t2, t3 # a = b + c;
_after:
sub t1, t2, t3 # a = b - c;
In this version of the assembly implementation of the same C
code the beq
,
which stands for "branch equal", is used. However maintaining the same equal
testing condition as in the C
code cause the order of the statements to be
inverted in the assembly code and requires an additional jump instruction.