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

ARM汇编自定义函数中如何使用循环 处理LR寄存器及倍数判断问题

ARM汇编计数程序问题解决方案

核心问题说明

  • 指令使用误区:内部循环不需要用BL跳转,BL仅用于函数调用,会自动修改LR寄存器存储返回地址,普通循环用B指令跳转即可,不会修改LR,不存在覆盖问题
  • 逻辑优先级错误:当前代码先判断8的倍数再判断3的倍数,若数值同时为二者倍数,会导致后写入的0xbbbb覆盖先写入的0xffff,无法得到要求的0xffbb
  • 返回地址存储冗余:不需要在数据段预定义空间存储LR,直接通过栈PUSH/POP操作保存恢复LR更简洁
  • 计数起始值错误:初始r0=10后进入_loop先执行add R0, #1,会跳过10直接从11开始计数

具体修改方案

1. 3的倍数判断循环实现

直接在_multOf3函数内实现循环,不需要单独拆成函数,用B跳转实现迭代,完全不修改LR:

_multOf3:
    PUSH {LR}         @ 直接用栈保存返回地址,不需要存到数据段
    MOV R1, R0        @ 复制待判断数值到临时寄存器R1,不修改原R0
3_loop:
    SUBS R1, #3       @ 每次减3,影响标志位
    BPL 3_loop        @ 如果结果>=0就继续循环
    @ 循环结束后R1为-2/-1/0,等于0就是3的倍数
    CMP R1, #0
    BNE _multOf3_end  @ 不是3的倍数直接返回
    @ 是3的倍数,判断是否同时是8的倍数
    CMP R3, #0xffff
    MOVEQ R3, #0xffbb
    MOVNE R3, #0xbbbb
_multOf3_end:
    POP {PC}          @ 直接把栈里存的LR弹到PC,完成返回

2. 其他逻辑修正

  • 调整_loop的计数初始值,保证从10开始计数
  • 简化所有函数的LR保存逻辑,统一用栈操作
  • 删掉冗余的数据段返回地址存储逻辑,减少代码复杂度

完整可运行修改后代码

.section    .text
.global _start

_start:
    MOV R0, #9        @ 初始设为9,进循环先加1得到10,符合计数要求
    BL  _loop
_end:   
    B   _end

_loop:
    ADD R0, #1                  @ 递增计数
    MOV R3, #0                  @ 重置R3
    CMP R0, #50                 @ 到50就退出
    BEQ _end

    BL  _multOf8                @ 先判断8的倍数
    BL  _multOf3                @ 再判断3的倍数,处理同时满足的情况

    B   _loop

_multOf8:
    PUSH {LR}
    AND R1, R0, #7
    CMP R1, #0
    MOVEQ R3, #0xffff           @ 是8的倍数先赋值0xffff
    POP {PC}

_multOf3:
    PUSH {LR}
    MOV R1, R0
3_loop:
    SUBS R1, #3
    BPL 3_loop
    CMP R1, #0
    BNE _multOf3_end
    CMP R3, #0xffff
    MOVEQ R3, #0xffbb
    MOVNE R3, #0xbbbb
_multOf3_end:
    POP {PC}

内容的提问来源于stack exchange,提问作者Hamza Qureshi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 09:45:04