2016-03-28 96 views
0

这是作业。我一直在试图弄清楚我现在做了什么错误。分配是:ARM loop cmp问题

考虑下面的代码在C:

int foo(int a, int b) 
{ 
if (a > b) return 0; 
if (a == b) return b; 
return a + foo(a+1, b); 
} 

实现在装配此功能。从 函数分支回来后,输出应如下所示。如果用户输入4 然后10:4 10 49

END

如果用户输入10,则4:

END

我的代码,以便远为:

@main program 
_start:   
    mov sp,#0x100000  @ set up stack 

    ldr r4,=0x101f1000  
    @ ASCII codes stored 
    @ at [r4] get printed 

    @ get input 
    bl get_int 
    mov r5, r0 
    bl get_int 
    mov r6, r0 

    @ mov a to r0 b to r1 
     mov r0, r5 
     mov r1, r6 

    @ branch to the function you write 
     bl foo 

    @ print the number in r0 after branching back from your function 
     bl print10 

     @ branch to exit 
     b my_exit 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
@  Your code starts here  @ 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 

foo: 
     cmp r0,r1 
     blt Less 
     bge More 
     mov r0,r1 
     b Exit 
Less: 
     mov r3,r0 
     add r0,r0,#1 
     add r3,r3,r0 
     cmp r0,r1 
     blt More 
     mov r0,r3 
More: 
     mov r0,#0 
Exit: 
     bx lr 

我遇到的问题是当我运行它时,不管输入什么数字,我总是得到0的输出。

+0

我不确定你在'Less:'上试图做什么,但它是不正确的。你应该做的就是用参数'a + 1,b'调用'foo'并返回结果加上'a'的当前值。 – Michael

+0

'bge'不是[正确的条件](https://community.arm.com/groups/processors/blog/2010/07/16/condition-codes-1-condition-flags-and-codes)for'更多',它只是'bgt',因为你想等于返回一个不同的值(a == b或R0 == R1)。您可以使用递归或* inline *其余的'foo',而不使用递归。我会检查[编译器的功能](https://godbolt.org/g/ivsdCn)。 –

+0

谢谢你artless。我将其改为bgt,并能够更明确地指出我做错了什么。最后我把它改成了L2和L2。得到它为我需要的结果工作。再次感谢你 – Fireurza

回答

1

你缺少的是如何传递参数并返回一个值。在ARM ABI,相当于:

int less(int a, int b) 

是:

  • a(第一个参数)在R0
  • b(第二个参数)传递在R1通过
  • 返回值必须写入r0
  • Mov lrpc从功能返回

所以调用less功能,您需要: - 移动a到R0 - 移动b到R1 - 调用函数(bllt) - 确保调用bl(分公司和链接),而不是一个简单的b(分支)。转移和链接的形式复制bl后的指令的地址,允许返回 - 从R0

得到的结果,您还需要carreful,当你调用一个函数,r0-r3将被破坏。如果您需要修改其他寄存器,则需要将它们推入堆栈并在返回之前进行恢复。