Reputation: 2274
I'm trying to add a user inputted number to a every element in an array. I had everything working until I realized that the original array was not being updated. Simple, I thought, just store the value back into the array and move on with life. Sadly, this doesn't seem to be quite so simple.
As the title suggests, I'm using ARMv7 and writing assembly. I've been using this guide to understand the basics and to have some good code to look at. When I run the example code given here it works fine: str r2, [r3]
puts whatever is in r2
into what r3
points at. The following is my attempt to do the same thing which gives me a Signal 11 occurred: SIGSEGV (Invalid memory segment access)
and Execution stopped at: 0x0000580C STR r3,[r5,#0]
:
@ Loop and add value to all values in array regardless of array length
@ Setup loop
@ r4 comes from above and the scanf value, I've checked the registers and the value is correct
mov r0, #0
ldr r1, =array_b
ldr r2, addrArr
loop: @ Start loop to add inputed number to every value in array
add r3, r2, r0
ldr r3, [r3]
add r3, r3, r4 @ Add input to each index in array
add r5, r2, r0 @ Pointer to location in array
str r3, [r5] @ Put new value into array
cmp r0, r1 @ Check for end of array
addne r0, r0, #4 @ Not super necessary but it shows one of the cool things ARM can do, condition math
bne loop @ Branch if not equal
beq doneLoop @ Branch if equal
doneLoop: @ End loop
Here are the vars
.align 2
array:
.word 0
.word 1
.word 2
.word 3
.word 4
.word 5
.word 6
.word 7
.equ array_b, .-array
addrArr: .word array
My understanding is that str
takes the source first and the destination second (which is different from other instructions for some reason). So r5
is used to calculate where in the array to store the value and r3
has the value from the add
instruction. I've checked and the value in r5
is valid, ie: it's the start of the array and the array_b is the proper length (32 in this case). I've also tried doing =array
instead of addrArr
but they give the same value and the same segfault message.
Upvotes: 2
Views: 4145
Reputation: 634
This is because there is historically in systems two major kind of memories :
Many systems do no use ROM directly, instead the data can be loaded from an other permanent support, for example a floppy disc, a tape or a hard disc into RAM. In order to avoid a program writing to RAM memory that wasn't supposed to be written, the RAM can be divided in multiple areas, using segmented memory.
Not all system features this, so it really depends on the architecture. If segmented memory is used, it basically makes the processor quit the application when you try to write to a segment of RAM that is designed to be read only. This is exactly what appears to be your problem here.
In order to solve this you should declare your array, which is a variable and should be stocked in RAM, by precedding it by .data
.
On the other hand your executable instructions should be placed in the read only segment marked with the assembler directive .text
Upvotes: 1