编写一个程序来计算ARM汇编语言中整数的阶乘

时间:2016-10-11 03:07:59

标签: assembly arm

给定一个整数,我必须编写一个返回其阶乘值的函数。

这是我的阶乘函数代码:

bl getnum

move r3, r0

mov r1, #1   -- counter

mov r4, r0


loop:
   sub r0, r0, #1

   mul r3, r0, r3

   add r1, r1, #1  

   subs r1, r4  -- check if counter = the initial r0
beg loop

mov r0, r3

bl printnum

但是,此代码会产生错误的结果。例如,当我输入5时,它会给出20而不是120.有人可以帮我找出出错的地方吗?我的逻辑推理似乎有效,但我不知道是否出现语法错误导致程序以不同的方式运行

2 个答案:

答案 0 :(得分:4)

sub将减法的结果写回目标操作数。这不是你想要的 - 你只是想做一个比较,所以你应该使用cmp

cmp r1, r4  -- cmp always updates the flags, so you don't need to write cmps
bne loop    

但是,您的代码无法处理n为0或1的情况。此外,当您已经拥有一个非常合适的计数器时,没有必要使用额外的计数器(r1)在r0。所以你可以把它重写成这样的东西:

mov r3, #1  -- default value
loop:
  cmp r0, #1
  -- if (n > 1) { r3 *= n; n--; goto loop; }
  mulgt r3, r0, r3
  subgt r0, r0, #1
  bgt loop

答案 1 :(得分:0)

请阅读这篇精彩的post

作为旁注,请注意您不会跟随ARM调用convention of ARM以确保正确的上下文切换。

我认为你使用了太多的寄存器,试着减少它们的数量。更容易跟踪代码流和调试。

这是我的最终建议:

mov r3, #1
cmp r0, #0
beq end

factorial:
    mul r3, r3, r0
    sub r0, r0, #1 
    beg factorial 
end:              
    mov r0, r3

我认为在你的解决方案中你应该改变

subs r1, r4  -- check if counter = the initial r0

进入

cmp r1, r4  -- check if counter = the initial r0

因此,您将检查r1 > r4是否不更改r1,否则您将在一次循环后退出。