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

如何在循环中使用ARM ADCS指令?解决CMP破坏标志位问题

解决ARM汇编中ADCS与CMP标志位冲突的问题

核心问题分析

你的代码中,ADCS指令依赖进位标志位C完成带进位的BCD加法,但后续CMP指令会直接覆盖所有条件标志位(包括C),导致下一次ADCS无法正确获取上一次的进位状态。

可行解决方案

方案1:使用MRS/MSR指令保存并恢复标志位

ARM架构中,可通过MRS(从状态寄存器读取到通用寄存器)和MSR(从通用寄存器写入状态寄存器的标志位域),在执行CMP前后保留ADCS设置的进位标志。

修改后的代码如下:

ldr r8, =#0
    ldr r9, =#15
    adds r7, r8, #0

ADDLOOP:
    and r4, r0, r9
    and r5, r1, r9

    adcs r6, r4, r5       ; 执行带进位加法,设置C标志
    orr r7, r6, r7

    mrs r10, cpsr         ; 保存当前标志位状态到r10

    add r8, r8, #1
    mov r9, r9, lsl #4

    cmp r8, #3            ; 此处覆盖标志位,但已提前保存
    bgt ADDEND

    msr cpsr_f, r10       ; 恢复之前保存的标志位(重点保留C标志)
    b ADDLOOP             ; 用b代替bl,避免lr寄存器被覆盖导致错误

ADDEND:
    mov r0, r7

方案2:重构循环逻辑,避免使用CMP

如果不想保存标志位,可调整循环计数方式,用不破坏进位标志的逻辑判断循环终止。比如改用递减计数,结合SUBS和条件跳转,但需注意SUBS仍会修改标志位,仅适用于进位无需跨循环保留的场景:

ldr r8, =#4           ; 设置循环执行4次
    ldr r9, =#15
    adds r7, r8, #0

ADDLOOP:
    and r4, r0, r9
    and r5, r1, r9

    adcs r6, r4, r5
    orr r7, r6, r7

    subs r8, r8, #1       ; 递减计数并设置标志位
    mov r9, r9, lsl #4

    bne ADDLOOP           ; 计数未到0则继续循环

ADDEND:
    mov r0, r7

额外注意点

  • 原代码中bl ADDLOOP是错误用法:bl会将当前指令下一条地址存入lr寄存器,多次循环会覆盖lr,导致程序后续无法正确返回,需改为b ADDLOOP实现循环跳转。
  • 保存标志位时,需选用闲置的通用寄存器(如示例中的r10),避免干扰其他逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:40:22