使用寄存器的 RISCV 函数
RISCV function using registers
这段代码使用 RISCV 的返回值是多少
考虑 c 的形式是 int fun(int n)
fun:
addi s0, zero, 0
addi s1, zero, 1
add t0, zero, a0
loop:
beq s0, t0, exit
add s1, s1, s1
addi s0, s0, 1
jal zero, loop
exit:
add a0, zero, s1
jalr zero, 0(ra)
有时,在分析汇编时,直接了解 C 的情况,然后进行简化可能会有所帮助:
int fun(int n) {
int s0 = 0;
int s1 = 1;
int t0 = n; // n is in a0
loop:
if (s0 == t0) {
goto loop_exit;
}
s1 = s1 + s1;
s0 = s0 + 1;
goto loop;
loop_exit:
return s1; // Returns in a0
}
我们可以看到不需要复制到t0
,我们可以直接使用n
。此外,这个 goto
结构看起来很像一个 while
循环,在开始时检查循环的条件。
int fun(int n) {
int s0 = 0;
int s1 = 1;
while (s0 != n) {
s1 += s1;
s0 += 1;
}
return s1;
}
我们现在可以看到 s1
将从 1 开始,然后翻倍 n
次。我们可以重写给出描述性名称,并将 while
替换为 for
:
int fun(int n) {
int value = 1;
for (int counter = 0; counter != n; counter += 1) {
value += value;
}
return value;
}
感谢编译器的美,这三组代码actually generate同一个程序集(在那个特定的编译器上,在我写这篇文章的时候)。
当n
小于int
的精度时,此函数表现为将1左移n
位。
在这种非边缘情况下,fun
等同于:
int fun(int n) {
return 1 << n;
}
如果 n
至少是 int
的精度,那么您会遇到有符号整数溢出,这会导致实现定义的行为。
这段代码使用 RISCV 的返回值是多少
考虑 c 的形式是 int fun(int n)
fun:
addi s0, zero, 0
addi s1, zero, 1
add t0, zero, a0
loop:
beq s0, t0, exit
add s1, s1, s1
addi s0, s0, 1
jal zero, loop
exit:
add a0, zero, s1
jalr zero, 0(ra)
有时,在分析汇编时,直接了解 C 的情况,然后进行简化可能会有所帮助:
int fun(int n) {
int s0 = 0;
int s1 = 1;
int t0 = n; // n is in a0
loop:
if (s0 == t0) {
goto loop_exit;
}
s1 = s1 + s1;
s0 = s0 + 1;
goto loop;
loop_exit:
return s1; // Returns in a0
}
我们可以看到不需要复制到t0
,我们可以直接使用n
。此外,这个 goto
结构看起来很像一个 while
循环,在开始时检查循环的条件。
int fun(int n) {
int s0 = 0;
int s1 = 1;
while (s0 != n) {
s1 += s1;
s0 += 1;
}
return s1;
}
我们现在可以看到 s1
将从 1 开始,然后翻倍 n
次。我们可以重写给出描述性名称,并将 while
替换为 for
:
int fun(int n) {
int value = 1;
for (int counter = 0; counter != n; counter += 1) {
value += value;
}
return value;
}
感谢编译器的美,这三组代码actually generate同一个程序集(在那个特定的编译器上,在我写这篇文章的时候)。
当n
小于int
的精度时,此函数表现为将1左移n
位。
在这种非边缘情况下,fun
等同于:
int fun(int n) {
return 1 << n;
}
如果 n
至少是 int
的精度,那么您会遇到有符号整数溢出,这会导致实现定义的行为。