ARMv7 程序集将值存储在数组中
ARMv7 assembly store values in an array
我正在尝试将用户输入的数字添加到数组中的每个元素。在我意识到原始数组没有更新之前,我一切正常。我想很简单,只需将值存储回数组并继续生活。遗憾的是,这似乎并不那么简单。
如标题所示,我正在使用 ARMv7 并编写汇编。我一直在使用 this guide 来了解基础知识并查看一些好的代码。当我 运行 这里给出的示例代码工作正常时: str r2, [r3]
将 r2
中的任何内容放入 r3
指向的位置。以下是我尝试做同样的事情,它给了我 Signal 11 occurred: SIGSEGV (Invalid memory segment access)
和 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
这是变量
.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
我的理解是str
首先是源,其次是目标(由于某些原因,这与其他指令不同)。因此 r5
用于计算数组中存储值的位置,而 r3
具有来自 add
指令的值。我检查过 r5
中的值是有效的,即:它是数组的开始,array_b 是正确的长度(在本例中为 32)。我也尝试过 =array
而不是 addrArr
但它们给出了相同的值和相同的段错误消息。
这是因为历史上系统中有两种主要的记忆:
- ROM,只读存储器,不能写入,只能存储程序和常量数据
- RAM,随机存取存储器,可以读写。用于存储变量。
很多系统不直接使用ROM,而是可以从其他永久性支持,例如软盘、磁带或硬盘中将数据加载到RAM中。为了避免程序写入不应该写入的RAM内存,可以将RAM分成多个区域,使用分段内存。
并非所有系统都具有此功能,因此这实际上取决于体系结构。如果使用分段内存,当您尝试写入设计为只读的 RAM 段时,它基本上会使处理器退出应用程序。这正是您的问题所在。
为了解决这个问题,你应该声明你的数组,它是一个变量,应该存储在 RAM 中,在它前面加上 .data
。
另一方面,您的可执行指令应放在标有汇编程序指令的只读段中 .text
我正在尝试将用户输入的数字添加到数组中的每个元素。在我意识到原始数组没有更新之前,我一切正常。我想很简单,只需将值存储回数组并继续生活。遗憾的是,这似乎并不那么简单。
如标题所示,我正在使用 ARMv7 并编写汇编。我一直在使用 this guide 来了解基础知识并查看一些好的代码。当我 运行 这里给出的示例代码工作正常时: str r2, [r3]
将 r2
中的任何内容放入 r3
指向的位置。以下是我尝试做同样的事情,它给了我 Signal 11 occurred: SIGSEGV (Invalid memory segment access)
和 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
这是变量
.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
我的理解是str
首先是源,其次是目标(由于某些原因,这与其他指令不同)。因此 r5
用于计算数组中存储值的位置,而 r3
具有来自 add
指令的值。我检查过 r5
中的值是有效的,即:它是数组的开始,array_b 是正确的长度(在本例中为 32)。我也尝试过 =array
而不是 addrArr
但它们给出了相同的值和相同的段错误消息。
这是因为历史上系统中有两种主要的记忆:
- ROM,只读存储器,不能写入,只能存储程序和常量数据
- RAM,随机存取存储器,可以读写。用于存储变量。
很多系统不直接使用ROM,而是可以从其他永久性支持,例如软盘、磁带或硬盘中将数据加载到RAM中。为了避免程序写入不应该写入的RAM内存,可以将RAM分成多个区域,使用分段内存。
并非所有系统都具有此功能,因此这实际上取决于体系结构。如果使用分段内存,当您尝试写入设计为只读的 RAM 段时,它基本上会使处理器退出应用程序。这正是您的问题所在。
为了解决这个问题,你应该声明你的数组,它是一个变量,应该存储在 RAM 中,在它前面加上 .data
。
另一方面,您的可执行指令应放在标有汇编程序指令的只读段中 .text