dcalvert
dcalvert

Reputation: 73

How can I do this section of code, but using auto-indexing with ARM Assembly

this works, but I have to do it using auto-indexing and I can not figure out that part.

writeloop:
  cmp r0, #10
  beq writedone
  ldr r1, =array1
  lsl r2, r0, #2
  add r2, r1, r2
  str r2, [r2]
  add r0, r0, #1
  b writeloop

and for data I have

.balign 4
array1: skip 40

What I had tried was this, and yes I know it is probably a poor attempt but I am new to this and do not understand

ldr r1, =array1

writeloop:
  cmp r0, #10
  beq writedone
  ldr r2, [r1], #4
  str r2, [r2]
  add r0, r0, #1
  b writeloop

It says segmentation fault when I try this. What is wrong? What I am thinking should happen is every time it loops through, it sets the element r2 it at = to the address of itself, and then increments to the next element and does the same thing

Upvotes: 0

Views: 1312

Answers (1)

artless-noise-bye-due2AI
artless-noise-bye-due2AI

Reputation: 22395

The ARM architechures gives several different address modes.

From ARM946E-S product overview and many other sources:

Load and store instructions have three primary addressing modes
- offset
- pre-indexed
- post-indexed.

They are formed by adding or subtracting an immediate or register-based offset to or from a base register. Register-based offsets can also be scaled with shift operations. Pre-indexed and post-indexed addressing modes update the base register with the base plus offset calculation. As the PC is a general purpose register, a 32‑bit value can be loaded directly into the PC to perform a jump to any address in the 4GB memory space.

As well, they support write back or updating of the register, hence the reason for pre-indexed and post-indexed. Post-index doesn't make much sense without write back.

Now to your issue, I believe that you want to write the values 0-9 to an array of ten words (length four bytes). Assuming this, you can use indexing and update the value via add. This leads to,

  mov r0, #0       ; start value
  ldr r1, =array1  ; array pointer

writeloop:
  cmp r0, #10
  beq writedone
  str r0, [r1, r0, lsl #2] ; index with r1 base by r0 scaled by *4
  add r0, r0, #1
  b writeloop
writedone:
; code to jump somewhere else and not execute data.

.balign 4
array1: skip 40

For interest a more efficient loop can be done by counting and writing down,

  mov r0, #9       ; start value
  ldr r1, =array1  ; array pointer

writeloop:
  str r0, [r1, r0, lsl #2] ; index with r1 base by r0 scaled by *4
  subs r0, r0, #1
  bne writeloop

Your original example was writing the pointer to the array; often referred to as 'value equals address'. If this is what you want,

  ldr r0, =array_end ; finished?
  ldr r1, =array1    ; array pointer
write_loop:
  str r1, [r1], #4  ; add four and update after storing
  cmp r0, r1
  bne write_loop
; code to jump somewhere else and not execute data.

.balign 4
array1: skip 40
array_end:

Upvotes: 1

Related Questions