我有兴趣将C中的Fibonacci序列代码转换为ARM汇编语言. C中的代码如下:
#include <iostream>
using namespace std;
int main()
{
int range, first = 0 , second = 1, fibonacci;
cout << "Enter range for the Fibonacci Sequence" << endl;
cin >> range;
for (int i = 0; i < range; i++)
{
if (i <=1)
{
fibonacci = i;
}
else
{
fibonacci = first and second;
first = second;
second = fibonacci;
}
}
cout << fibonacci << endl;
return 0;
}
我将此转换为装配的尝试如下:
ldr r0, =0x00000000 ;loads 0 in r0
ldr r1, =0x00000001 ;loads 1 into r1
ldr r2, =0x00000002 ;loads 2 into r2, this will be the equivalent of 'n' in C++ code,
but I will force the value of 'n' when writing this code
ldr r3, =0x00000000 ;r3 will be used as a counter in the loop
;r4 will be used as 'fibonacci'
loop:
cmp r3, #2 ;Compares r3 with a value of 0
it lt
movlt r4, r3 ;If r3 is less than #0, r4 will equal r3. This means r4 will only ever be
0 or 1.
it eq ;If r3 is equal to 2, run through these instructions
addeq r4, r0, r1
moveq r0,r1
mov r1, r4
adds r3, r3, #1 ;Increases the counter by one
it gt ;Similarly, if r3 is greater than 2, run though these instructions
addgt r4, r0, r1
movgt r0, r1
mov r1, r4
adds r3, r3, #1
我不完全确定如果你在大会上发表声明你是怎么做的,但这对我来说是次要问题.我更感兴趣的是,我如何结合if语句来测试“计数器”与“范围”进行比较的初始条件.如果反击
cmp r3, r2
;If r3 < r2
{
<code>
}
;else, stop
此外,为了正确循环,我能够添加:
cmp r3, r2
bne loop
这样循环迭代直到r3 = r2?
提前致谢 :)
最佳答案 将if语句放在循环中是不明智的.摆脱它.
优化(有点)独立的Fibonacci函数应该是这样的:
unsigned int fib(unsigned int n)
{
unsigned int first = 0;
unsigned int second = 1;
unsigned int temp;
if (n > 47) return 0xffffffff; // overflow check
if (n < 2) return n;
n -= 1;
while (1)
{
n -= 1;
if (n == 0) return second;
temp = first + second;
first = second;
second = temp
}
}
与阶乘非常相似,优化Fibonacci序列在现实世界计算中有些无意义,因为它们很快就会超过32位屏障:它是12阶段的阶乘,47阶段是Fibonacci.
如果您确实需要它们,那么您可以通过非常短的查找表获得最佳服务.
如果您需要为更大的值完全实现此功能:
https://www.nayuki.io/page/fast-fibonacci-algorithms
最后但并非最不重要的,这是上面汇编中的函数:
cmp r0, #47 // r0 is n
movhi r0, #-1 // overflow check
bxhi lr
cmp r0, #2
bxlo lr
sub r2, r0, #1 // r2 is the counter now
mov r1, #0 // r1 is first
mov r0, #1 // r0 is second
loop:
subs r2, r2, #1 // n -= 1
add r12, r0, r1 // temp = first + second
mov r1, r0 // first = second
bxeq lr // return second when condition is met
mov r0, r12 // second = temp
b loop
请注意,最后一个bxeq lr可以放在subs之后,这可能看起来更符合逻辑,但考虑到Cortex系列的多次发布功能,它按此顺序更好.
它可能不是您正在寻找的答案,但要牢记这一点:循环中的单个if语句会严重削弱性能 – 嵌套的甚至更多.
而且几乎总有办法避免这些.你只需要寻找它们.