我正试图解决一个计数器从10到50的问题。对于每个数字,我必须检查它是否是8的倍数(如果是,则我在R3中存储0xffff(,或者它是否是3的倍数(并且我将存储0xbbbb(,或者是否是两者的倍数(在R3中我存储0xffbb(。
为了检查这个数字是否是3的倍数,我的计划是从这个数字中减去3,直到它达到0或小于3。我很难弄清楚如何在自定义函数中使用循环。这是我到目前为止的代码:
.section .data
.balign 4
return_start: .word 0
.balign 4
return_loop: .word 0
.balign 4
return_8: .word 0
.balign 4
return_3: .word 0
.balign 4
return_3loop: .word 0
.section .text
.global _start
/* .func _loop
.func _multOf8
.func _multOf3 */
_start:
LDR R1, addr_return_start
STR lr, [R1]
mov r0, #10 /* Start with 10 */
BL _loop
LDR lr, addr_return_start
LDR lr, [LR]
_loop:
add R0, #1 /* increment by 1 */
MOV r3, #0 /* resetting r3 */
CMP R0, #50 /* check if it is 50, if it is then go to the end */
BEQ _end
/* else check if it is a multple of 8 */
BL _multOf8
/* check if it is a multiple of 3 */
BL _multOf3
B _loop
_multOf8:
/* save LR */
LDR R1, addr_return_8
STR lr, [R1]
AND r1, r0, #7
CMP r1, #0
MOVEQ r3, #0xffff /* if it is a multiple of 8 */
/* else return */
LDR LR, addr_return_8
LDR LR, [LR]
BX LR
_multOf3:
LDR R1, addr_return_3
STR lr, [R1]
/* if it is a multiple of 3 */
/* will need to subtract it continuously? */
PUSH R0
BL _3loop
POP R0
LDR LR, addr_return_3
LDR LR, [lr]
BX lr
_3loop:
LDR R1, addr_return_3loop
STR lr, [R1]
_end: B _end
addr_return_start: .word return_start
addr_return_loop: .word return_loop
addr_return_8: .word return_8
addr_return_3: .word return_3
addr_return_3loop: .word return_3loop
正如您所看到的,在函数_multOf3
中,我正试图分支到_3loop
。问题是,我不知道如何处理LR
以及如何从这个循环返回。我觉得如果我要存储LR,每次迭代循环时它都会被不断覆盖。
任何帮助都将不胜感激!请注意,我是ARM汇编的初学者。
ARM中的循环并不太复杂。有几种方法可以实现一个。通常,您需要留出一个寄存器作为循环计数器。下面的示例用于递减循环。
_loop: /* R2 is the loop counter */
/* do stuff here */
subs R2,R2,#1 /* the S at the end sets the flags accordingly. If the result is zero,
the zero flag will be set and BNE will not branch.
BNE _loop
/* if R2 = 0, execution will fall through to here, otherwise it jumps back to the loop's start
递增循环需要额外的步骤,因为您需要将循环计数器的值与所需的端点进行比较:
_loop /* R2 is the loop counter */
/* do stuff here */
add R2,R2,#1 /* no need for S at the end, it does us no good here. */
CMP R2,#50 /* 50 was arbitrarily chosen for this example. */
BNE _loop /* this just checks if they're not equal, for this example it's sufficient but
it's better to use BLS for signed numbers or BLO/BCC for unsigned */