You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM汇编访问未对齐内存位置报错求助——数组复制加值作业问题

解决ARMSim#中“未对齐内存访问”错误的问题

嘿,我一眼就看到了问题所在——你在循环里不小心把源数组的地址指针给覆盖了,导致第二次循环去访问了一个未对齐的内存地址!让我给你拆解清楚,再帮你把代码修好。

错误根源分析

咱们一步步看你的代码执行流程:

  1. 一开始ldr r8,=array_source,这时候r8是源数组的起始地址,完全没问题。
  2. 第一次进入循环,你执行了ldr r8, [r8]——这一步直接把r8从数组地址改成了数组第一个元素的值(42),这是核心错误!
  3. 接下来add r8, r8, r5让r8变成了42+5=47(也就是十六进制的0x2f),然后你把这个值存到了目标数组。
  4. 第一次循环结束后,你没有恢复r8的地址作用,反而去操作了r0(这里r0一开始是array_length的地址,你循环里的add r0, r0, #4完全没用)。
  5. 第二次循环时,你又执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 06:12:40