Recursion 使用递归和堆栈计算x^n的ARM程序集
我有一个作业,要求我使用递归计算x^n。函数power的C源代码已经提供,我必须将其翻译成汇编语言,但是我对汇编还不熟悉,有点卡住了,所以不知道该怎么办 以下是我目前的代码:Recursion 使用递归和堆栈计算x^n的ARM程序集,recursion,assembly,arm,stack,Recursion,Assembly,Arm,Stack,我有一个作业,要求我使用递归计算x^n。函数power的C源代码已经提供,我必须将其翻译成汇编语言,但是我对汇编还不熟悉,有点卡住了,所以不知道该怎么办 以下是我目前的代码: AREA powerXn, CODE, READONLY ENTRY MOV r0, #2 ;Value of x. MOV r1, #3 ;Value of n.
AREA powerXn, CODE, READONLY
ENTRY
MOV r0, #2 ;Value of x.
MOV r1, #3 ;Value of n.
ADR sp, stack ;Points sp to start of stack.
BL main
loop B loop
main STMFD sp!, {r0, r1, r2, r3, lr} ;Pushes registers on to stack.
BL power
LDMFD sp!, {r0, r1, r2, r3, pc} ;Pops values from stack.
power STMFD sp!, {r0, r1, lr} ;Pushes registers on to stack.
CMP r1, #0 ;Checks the base case
MOVEQ r2, #1 ;Sets r2 to be 1 if base case is reached
BNE test ;If base case not reached, jump to test.
MUL r3, r0, r2
LDMFD sp!, {r0, r1, pc}
test TST r1, #1 ;Checks if r1 (n) is odd
BNE odd ;If it is odd, jump to odd
BEQ even ;Otherwise jump to even
odd SUB r1, r1, #1 ;Subtract 1 from r1 (n).
BL power ;Recurse back to power.
MUL r3, r0, r2
LDMFD sp!, {r0, r1, pc}
even ;Not sure what to do here and not sure if what i have done so far is right.
AREA powerXn, DATA, READWRITE
ALIGN
space 0x200
stack DCD 0x00
END
我需要翻译的C源代码是:
int power(int x, unsigned int n){
int y;
if (n == 0)
return 1;
if (n & 1) // if n is odd
return x * power(x, n - 1);
else { // if n is even
y = power(x, n >> 1); // n >> 1 means n/2
return y * y;
}
}
您似乎更熟悉C,因此我建议您去尝试他们的C-to-assembler功能。您所要做的就是选择一个正确的编译器(ARMGCC有一些选项)并查看汇编代码。当然,我强烈反对在不试图理解代码的情况下简单地复制代码,但该网站至少应该给你一个关于如何做的线索。我目前正在用FASM学习x86汇编程序,这个网站是我在研究过程中经常访问的地方。这是错误的。此外,它还有没有注释的说明。很难说您想用
MUL r3、r0、r2做什么,例如,什么时候应该是return 1
。此外,返回值通常在r0
中,因此保存/还原时即使计算正确也会覆盖结果。如何检查代码的正确性?你真的能编译并运行它吗?对n有什么限制吗?(因为溢出是这里的一个问题)。我把这个问题误读为没有递归/堆栈的问题。(递归适用于算法的理论讨论,或使用智能编译器的语言,但在asm中是一种糟糕的实现策略)。该算法可以通过在arg设置中移动乘法进行迭代,使其成为尾部递归,然后转换为循环并简化。参见亚历山大·斯捷潘诺夫的《埃及人的战利品:演讲2第1部分:(包括演讲系列的播放列表),在该演讲的第2部分,斯捷潘诺夫将+
概括为*
,在n
算法中,制作幂函数而不是从同一右移进行乘法,并对设定位执行特殊操作。感谢您的回复和链接!这看起来很有帮助,所以我会留意的。