2016-04-19 39 views
0

对于作业分配,我已经被赋予了一个递归C函数来计算我需要转换为ARM程序集的整数分区。事情我知道ARM汇编:将递归C函数转换为ARM程序集?

1)R0将举行电话

2)R1R2的返回值,R3是参数寄存器

的代码如下:

int count_partitions(int n, int m) { 

if (n == 0) 
    return 1; 

else if(n < 0) 
    return 0; 

else if (m == 0) 
    return 0; 

else 
    return count_partitions(n - m, m) + count_partitions(n, m - 1); 
} 

我相信我已经正确地做了第​​一个3 if & else-if陈述。我最后的else声明的逻辑是找到count_partitions(n,m-1),将它存储到堆栈中,然后找到count_partitions(n-m, m),并将其添加到从堆栈获得的先前返回值 - 但是,我的代码似乎并不工作?

我附上了我的尝试解决方案,并对C代码的不同部分及其相应的汇编代码进行了颜色编码。任何人都可以让我知道什么是错的?

enter image description here

+1

您是否尝试过使用生成的汇编代码的指导GCC(或红clangs)的能力? –

+0

我不能完全解读那些微不可读的代码图片,但[这是编译器认为的](https://gcc.godbolt.org/#compilers :!((编译器:armhfg482,选项:' - O2 + -marm '源:' INT + count_partitions(INT + N,+ INT + M)+%7B +%0Aif +(N +%3D%3D + 0)+%0A ++++返回+ 1%3B +%0Aelse +如果第(n + %3C + 0)+%0A ++++返回+ 0%3B +%0Aelse + IF +(M +%3D%3D + 0)+%0A ++++返回+ 0%3B +%0Areturn + count_partitions(N + - + m,+ m)+%2B + count_partitions(n,+ m + - + 1)%3B +%0A%7D')),filterAsm :(指令:!t,labels:!t),版本:3)。 – Notlikethat

+0

您似乎不太可能需要将汇编器和递归结合到任何实际应用程序中。递归的真实世界用途很少,几乎在每种情况下都存在更好的非递归替代方案。特别是在99.99%的情况下,在嵌入式系统中使用递归是纯粹的废话。这是一个很好的方式来获得诉讼。 – Lundin

回答

0

您可以在CMP命令后使用,并跳到你的函数:

BEQ标签; BRANCH EQUAL

BNE标签; BRANCH NOT EQUAL

BLE标签;分支小于等于

BLT标签;分支小于

BGE标签; BRANCH GREATER THAN EQUAL

BGT标签; BRANCH GREATER THAN

0

我想我看到了几个问题:

  • 您认为nr1。这实际上在r0m将在r1,而不是r2。
  • 因此,您需要同时保存r0r1

一个清洁的解决方案是使用这样的:

_count_partitions: 
    ...    ; First part with comparison 
        ; but r1->r0 and r2->r1 

    push {r4-r5} 
    mov r4, r0  ; saved value of n 
    mov r5, r1  ; saved value of m 
    sub r0, r4, r5 ; n = n-m 
    bl _count_partitions 

    sub r1, r5, #1 ; m = m-1 
    mov r5, r1  ; result of first function 
    mov r0, r4  ; restore n 
    bl _count_partitions 

    add r0, r0, r5 ; cumulative result 
    pop {r4,r5} 
    pop {pc}