简体   繁体   中英

How can I use a while loop (or any loop) within a custom function in ARM Assembly?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM