有人能给我一个例子,说明如何在 ARM 汇编中仅使用此处列出的指令(用于视觉)来完成递归?
我正在尝试为类做一个递归斐波那契和阶乘函数。我知道递归是一个调用函数的函数,但我不知道如何在 ARM 中模拟它。
https://salmanarif.bitbucket.io/visual/supported_instructions.html
如果链接不起作用,我正在使用 visUAL,这些是我可以使用的唯一说明:
这不会加载 R4 的旧值,因此每次函数调用自身时 R4 都会加倍。
;VisUAL initializess all registers to 0 except for R13/SP, which is -16777216
MOV R4, #0
MOV R5, #1
MOV r0, #4
MOV LR, #16 ;tells program to move to 4th instruction
FIB
STMDB SP!, {R4-R6, LR} ;Stores necessary values on stack (PUSH command)
LDR R4, [SP] ;Loads older value for R4 from memory
ADD R4, R4, R5 ;Adds R5 to R4
STR R4, [SP], #8 ;stores current value for R4 to memory
MOV R5, R4 ;Makes R5 = R4
CMP R4, #144 ;If R4 >= 144:
BGE POP ;Branch to POP
MOV PC, LR ;Moves to STMDB(PUSH) statement
POP
LDMIA SP!, {R4-R6, LR} ;Pops registers off stack
END ;ends program
您需要使用堆栈、STMDB 和 LDMIA 指令。在具有“统一”符号的真正 ARM 工具上,它们还具有助记符 PUSH 和 POP。
斐波那契和阶乘并不是很好的例子,因为它们“不需要”递归。但让我们假装他们这样做。我会选择斐波那契,因为你没有 MUL 指令!?你想做这样的事情:
START
MOV R0, #6
BL FIB
END ; pseudo-instruction to make your simulator terminate
FIB ; int fib(int i) {
STMDB SP!, {R4,R5,R6,LR} ; int n, tmp;
MOV R4, R0 ; n = i;
CMP R0, #2 ; if (i <= 2) {
MOV R0, #1 ; return 1;
BLE FIB_END ; }
SUB R0, R4, #2 ; i = n-2;
BL FIB ; i = fib(i);
MOV R5, R0 ; tmp = i;
SUB R0, R4, #1 ; i = n-1;
BL FIB ; i = fib(i);
ADD R0, R0, R5 ; i = i + tmp;
FIB_END ; return i;
LDMIA SP!, {R4,R5,R6,PC} ; }
它应该以包含 fib(6) == 8 的 R0 终止。当然,这段代码非常低效,因为它重复调用 FIB 以获得相同的值。
STM 是必需的,因此您可以使用寄存器 r4、r5,因为另一个函数调用可以更改 r0-r3 和 LR。推LR和弹出PC就像B LR。如果您正在调用 C 代码,您应该推送偶数个寄存器以保持 SP 64 位对齐(我们在这里真的不需要这样做;忽略 R6)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句