0

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

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
dcalvert
  • 73
  • 1
  • 11
  • `add r2, r1, r2` .. `r1` is not set to anything. Also it's unclear why you are even reading from the array? Please specify what exactly you want to do. – Jester Jan 24 '19 at 23:49
  • I realized that after I submitted. I edited it to what I have now, which, to me, looks correct but it does a segment fault – dcalvert Jan 25 '19 at 00:13
  • 1
    My question stands. Why are you reading from the array? To make matters worse, you are reading into `r2` which will then be a null pointer and hence fault when you subsequently try to write through it. – Jester Jan 25 '19 at 01:12
  • The code loads from array1, but where is it supposed to store into? – rcgldr Jan 25 '19 at 03:25
  • I may not understand the question still. All this is supposed to do is take an empty array and then fill it with its own addresses. So the value at location 0 would be 0, then location 4 would be 4, and so on. So I don't think there is any reading going on, just writing – dcalvert Jan 25 '19 at 05:01
  • and its just supposed to store back into itself, I think thats the part im struggling to figure out @rcgldr – dcalvert Jan 25 '19 at 05:24
  • Then remove the `ldr r2, [r1], #4`, because that destroys the pointer in `r2` that you use in the next instruction. Use a debugger! – Peter Cordes Jan 25 '19 at 06:39
  • @PeterCordes Trust me, I would if I could haha. I have the program working in a normal way, but my professor specifies that we must use auto-indexing to access the array during both input and output. So that is what that is for. I just don't know how to do anything once that command is made – dcalvert Jan 25 '19 at 06:44
  • But why are you loading anything? You say in the text you're trying to set each element to point to itself. Are you trying to copy something? If so, where's the other array? Maybe you can write what you're trying to do in a language you do know (like C or pseudo-code), so we have something that makes some sense. – Peter Cordes Jan 25 '19 at 07:01
  • 1
    Even I don't know what I am doing, man. This assignment is strange. Essentially, what I am supposed to do is make the index = its memory location. So, array[0] = 0, array[1] = 4, array[2] = 8, going up 4 each time since that's how much it increments each time between memory locations. That may not be a good description, but maybe its something. As for why I'm loading anything, I just figured I needed to load the array first so that I could get the memory location, or is that wrong too? – dcalvert Jan 25 '19 at 07:22
  • 1
    @dcalvert - are you sure that is the goal? Based on the wording, storing the memory location could imply array[0] = &array[0], array[1] = &array[1], ..., storing pointers instead of offsets. – rcgldr Jan 25 '19 at 07:29
  • @rcgldr well, thats actually not the goal. Thats just my goal for now. I'm trying to somewhat figure out the actual assignment myself, and using other examples to do so. The real assignment is to take user input 10 times and put _that_ into the 10 indexes. But the closest thing to that I could find was the above example(first part). Then I tried converting it to use auto-indexing(second part), which screwed everything up. I'm sorry for my confusion, but I guess the silver lining was that I wasn't just trying to get a straight up answer to my assignment – dcalvert Jan 25 '19 at 07:43
  • 1
    What we are trying to tell you is that `ldr` is **reading** from the array! You do not want to read anything. Delete the `ldr` and change the `str` to `str r1, [r1], #4`. – Jester Jan 25 '19 at 12:07

1 Answers1

1

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:
artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Thank you for the well explained and detailed answer. I think this will help me be able to get me through to the other side. You're a life saver! – dcalvert Jan 25 '19 at 21:10
  • Yep I just used that and it worked perfectly. My problem was I thought I had to use ldr for some reason instead of str. Rookie mistake, I suppose. Once again, thank you so much – dcalvert Jan 25 '19 at 21:16