[英]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
將從n
開始,然后翻倍。 我們可以重寫給出描述性的名稱,並用while
代替for
:
int fun(int n) {
int value = 1;
for (int counter = 0; counter != n; counter += 1) {
value += value;
}
return value;
}
由於編譯器的優點,這三組代碼實際上生成了相同的程序集(在那個特定的編譯器上,在我寫這篇文章的時候)。
當n
小於int
的精度時,此 function 表現為 1 左移n
位。
在這種非邊緣情況下, fun
等價於:
int fun(int n) {
return 1 << n;
}
如果n
至少是int
的精度,那么您會遇到簽名的 integer 溢出,這會導致實現定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.