Keil Uvision中ARMv7汇编LDR指令读取数组大小异常问题
问题分析与解决方法
核心问题根源
你遇到的情况是符号size的定义/加载逻辑错误,或者Keil未正确初始化.data段内存,导致通过LDR r6, [r6]读取到无效的0值,直接终止循环。
可能的错误点及修复方案
误用
.equ宏定义搭配LDR =伪指令
如果你的size是用.equ size, N这种宏定义的编译期常量,那LDR r6, =size加载的是size这个符号的"地址"——但宏是编译时直接替换的文本,不占用内存空间,这个地址是无效的,对应内存自然是0。- 修复:直接用
MOV r6, #size加载立即数(只要size≤4096,ARM MOV指令支持直接加载),完全不需要从内存读取。
- 修复:直接用
.data段变量未被正确初始化
如果size是在.data段定义的内存变量(比如size: .word 5),但Keil模拟器默认可能没把.data的初始化数据加载到RAM中,导致该地址内存值为0。- 修复:
- 检查Keil工程设置:
Options for Target → Target,确认Memory Configuration里的RAM区域正确映射了.data段; - 勾选
Options for Target → Load Application → Initialize Memory,确保调试加载时自动初始化RAM中的.data数据。
- 检查Keil工程设置:
- 修复:
对
LDR =伪指令的理解偏差LDR r6, =size的作用是把size符号的地址加载到r6,之后你需要用LDR r6, [r6]读取该地址里的实际值。如果size不是内存变量(只是宏),这一步完全多余且错误;如果是内存变量,必须确保该地址有正确的初始化值。
正确代码示例
方案1:直接用立即数(推荐,编译期确定大小)
AREA FindMax, CODE, READONLY ENTRY Start MOV r6, #5 ; 直接加载数组大小(假设数组有5个元素) LDR r0, =array ; 加载数组首地址 LDR r4, [r0] ; 初始化最大值为数组第一个元素 MOV r1, #1 ; 从第二个元素开始比较 Loop LDR r2, [r0, r1, LSL #2] ; 读取array[r1] CMP r2, r4 MOVGT r4, r2 ; 如果当前元素更大,更新最大值 ADD r1, r1, #1 SUBS r6, r6, #1 BNE Loop ; 未循环完则继续 AREA DataSection, DATA, READWRITE array DCD 12, 45, 7, 68, 23 ; 测试数组 END
方案2:使用内存变量存储大小(需确保.data初始化)
AREA FindMax, CODE, READONLY ENTRY Start LDR r6, =size ; 加载size变量的地址 LDR r6, [r6] ; 读取size的实际值 LDR r0, =array LDR r4, [r0] MOV r1, #1 Loop LDR r2, [r0, r1, LSL #2] CMP r2, r4 MOVGT r4, r2 ADD r1, r1, #1 SUBS r6, r6, #1 BNE Loop AREA DataSection, DATA, READWRITE array DCD 12, 45, 7, 68, 23 size DCD 5 ; 定义数组大小的内存变量 END
内容的提问来源于stack exchange,提问作者Stranjer
相关产品推荐
相关产品推荐

