循环 – 在ARM程序集中创建嵌套的If语句

我有兴趣将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语句会严重削弱性能 – 嵌套的甚至更多.

而且几乎总有办法避免这些.你只需要寻找它们.

点赞