给定一个整数,我必须编写一个返回其阶乘值的函数。
这是我的阶乘函数代码:
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.有人可以帮我找出出错的地方吗?我的逻辑推理似乎有效,但我不知道是否出现语法错误导致程序以不同的方式运行
答案 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
,否则您将在一次循环后退出。