ARM汇编循环错误跳过比较:始终仅将x[i]存入z[i]问题排查
ARM汇编循环错误:始终仅从x数组取值存入z的问题排查与修复
核心问题分析
你代码里的致命错误有两个:
- 比较对象完全错误:
CMP r0, r1是在比较x数组的基地址(r0)和y数组的基地址(r1),而不是你想要的x[i]和y[i]的元素值。基地址是固定的内存地址,比较结果不会随循环变化,导致分支逻辑完全失效。 - 缺少写入z数组的指令:现有代码只是把x[i]/y[i]读到r2,但根本没有将值存入预留的z数组空间,等于所有取值操作都没有实际输出。
修复后的完整代码
; 显式初始化寄存器:加载变量地址并取出对应值 LDR r0, =x ; r0 = x数组基地址 LDR r1, =y ; r1 = y数组基地址 LDR r2, =z ; r2 = z数组基地址 LDR r3, =i ; 加载i的地址,取出初始值0 LDR r3, [r3] LDR r4, =size ; 加载size的数值10 LDR r4, [r4] loop: CMP r3, r4 ; 比较循环计数器i和数组长度size BGE done ; i >= size时退出循环 ; 先加载x[i]和y[i]到临时寄存器 LDR r5, [r0, r3, LSL #2] ; r5 = x[i](左移2位等价于×4,对应32位int的字节偏移) LDR r6, [r1, r3, LSL #2] ; r6 = y[i] CMP r5, r6 ; 真正比较x[i]和y[i]的元素值 BGE ygreat ; 若x[i] >= y[i],跳去存储y[i] ; 存储x[i]到z[i] STR r5, [r2, r3, LSL #2] B adding ygreat: ; 存储y[i]到z[i] STR r6, [r2, r3, LSL #2] adding: ADD r3, r3, #1 ; 循环计数器i自增 B loop done: B done ; 死循环暂停(可根据需求替换为退出逻辑) ; 数据段定义 x DCD 100, 3, -1, 2, 4, 4, 2, -1, 3, 100 y DCD -53, 247, 95, -7, 481, 91, -33, 1500, 29, -83 i DCD 0 size DCD 10 z SPACE 40 ; 预留z数组空间(10个32位int,共40字节) END
关键改动说明
- 修正比较逻辑:先将x[i]、y[i]加载到临时寄存器r5、r6,再比较这两个寄存器的元素值,而非数组基地址。
- 添加z数组写入操作:使用
STR指令将选中的元素存入z[i]的对应内存位置,解决原代码无输出的问题。 - 显式寄存器初始化:明确加载各变量的地址并取出数值,避免汇编器自动初始化的不确定性。
- 优化注释:让循环逻辑、寄存器用途更清晰。
调试建议
- 用汇编调试器单步执行,查看r0、r1、r5、r6的实时值,能快速发现基地址比较的错误。
- 检查内存中z数组的变化,确认写入指令是否生效。
内容的提问来源于stack exchange,提问作者LordOfChimichangas
相关产品推荐
相关产品推荐

