如何在ARM程序集中的自定义函数中使用while循环(或任何循环)



我正试图解决一个计数器从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 */

最新更新