给定一个整数,我必须编写一个函数来返回它的阶乘值。
下面是阶乘函数的代码:
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。有人能帮我找出哪里出了问题吗?我的逻辑推理似乎是有效的,但我不知道我是否犯了一个语法错误,导致程序以不同的方式运行
发布于 2016-10-11 14:18:53
sub
将减法的结果写回目标操作数。这不是您在这里想要的-您只是想做一个比较,所以您应该使用cmp
cmp r1, r4 -- cmp always updates the flags, so you don't need to write cmps
bne loop
但是,您的代码不能处理n
为0或1的情况。此外,当您在r0
中已经有一个非常合适的计数器时,也没有必要使用额外的计数器(r1
)。因此,您可以将其重写为以下内容:
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
发布于 2016-10-11 11:18:56
请阅读这篇精彩的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
的情况下检查是否为r1 > r4
,否则将在一次循环后退出。
https://stackoverflow.com/questions/39969925
复制相似问题