I am trying to solve a problem where I have a counter that goes from 10 to 50. For each number, I must check if it is a multiple of 8 (if it is, then I store 0xffff in R3), or if it is a multiple of 3 (and I would store 0xbbbb) or if it is a multiple of both (where I store 0xffbb in R3).
For checking if the number is a multiple of 3, my plan is to subtract 3 from the number until it either reaches 0 or is less than 3. I am struggling to figure out how I can use a loop within a custom function. Here is my code so far:
.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
As you can see, in the function _multOf3
I am attempting to branch off to _3loop
. The issue is, that I do not know what to do with LR
and how to return from this loop. I feel like if I was to store LR, it would continuously be overwritten each time we iterate through the loop.
Any help would be much appreciated! Please do note that I am a beginner in ARM Assembly.
Loops in ARM aren't too complicated. There's a couple ways to achieve one. Generally you'll need to set aside one register as a loop counter. The example below is for a decrementing loop.
_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
An incrementing loop takes an extra step, since you'll need to compare the value of the loop counter to the desired endpoint:
_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 */
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.