ARM汇编访问未对齐内存位置报错求助——数组复制加值作业问题
解决ARMSim#中“未对齐内存访问”错误的问题
嘿,我一眼就看到了问题所在——你在循环里不小心把源数组的地址指针给覆盖了,导致第二次循环去访问了一个未对齐的内存地址!让我给你拆解清楚,再帮你把代码修好。
错误根源分析
咱们一步步看你的代码执行流程:
- 一开始
ldr r8,=array_source,这时候r8是源数组的起始地址,完全没问题。 - 第一次进入循环,你执行了
ldr r8, [r8]——这一步直接把r8从数组地址改成了数组第一个元素的值(42),这是核心错误! - 接下来
add r8, r8, r5让r8变成了42+5=47(也就是十六进制的0x2f),然后你把这个值存到了目标数组。 - 第一次循环结束后,你没有恢复r8的地址作用,反而去操作了r0(这里r0一开始是array_length的地址,你循环里的
add r0, r0, #4完全没用)。 - 第二次循环时,你又执行
ldr r8, [r8],这时候r8是0x2f——ARM架构要求访问word类型数据时,地址必须是4的倍数(对齐访问),而0x2f除以4余3,不符合要求,自然就触发了“未对齐内存访问”的错误。
另外,你的代码还有两个小bug:
- 一开始
ldr r0,=array_length之后,你写了ldr r3, [r3]——这时候r3还没初始化,会读取一个随机地址的值,导致循环长度不正确。 - 循环计数器r6从#1开始,和长度6比较,这样只会执行5次循环,漏掉了数组的最后一个元素。
修复后的代码
我把这些问题都修正了,你可以直接用:
.data array_source: .word 42, 67, 81, 90, 124, -5 array_sink: .word 0, 0, 0, 0, 0, 0 array_length: .word 6 add_amount: .word 5 .text .global _start _start: ldr r8, =array_source @ r8 保存源数组的起始地址,全程不被覆盖 ldr r0, =array_length ldr r3, [r0] @ 正确读取数组长度到r3 ldr r4, =array_sink @ r4 保存目标数组的起始地址 ldr r5, =add_amount ldr r5, [r5] @ r5 保存要添加的数值 mov r6, #0 @ 循环计数器从0开始,确保遍历所有6个元素 begin_loop: cmp r6, r3 beq end_of_loop @ 计数器等于数组长度时退出循环 ldr r1, [r8] @ 用r1临时存储读取到的源数组元素 add r1, r1, r5 @ 给元素加上指定数值 str r1, [r4] @ 将结果存入目标数组 add r6, r6, #1 @ 计数器加1 add r8, r8, #4 @ 源数组地址加4,指向下一个元素 add r4, r4, #4 @ 目标数组地址加4,指向下一个位置 b begin_loop end_of_loop: @ 可选:添加程序退出指令,适配ARMSim#的环境 mov r7, #1 swi #0
关键修复点说明
- 保留地址指针:用r1作为临时寄存器存储读取的元素,不再覆盖r8的地址值,这样每次循环都能正确访问下一个元素的地址。
- 修正长度读取:把
ldr r3, [r3]改成ldr r3, [r0],正确读取数组长度。 - 完善循环逻辑:计数器从0开始,确保遍历数组的全部6个元素,不会遗漏。
- 正确递增地址:每次循环后给r8和r4加4,保证下一次访问的是数组的下一个word元素,地址始终对齐。
内容的提问来源于stack exchange,提问作者seaoftime
相关产品推荐
相关产品推荐

