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

ARM汇编实现10!陷入死循环求助:保留代码结构修复错误

修复ARM汇编阶乘代码的死循环问题

问题分析

你遇到的死循环核心原因是栈地址配置错误:原代码中SRAM_BASE EQU 0x40000000并非多数ARM芯片的可写SRAM起始地址,导致栈操作无法正确保存/恢复lr寄存器。执行LDMFD sp!, {r4, pc}时,pc被加载了错误的返回地址,从而陷入死循环。

循环本身的逻辑是正确的,通过条件指令实现了从n到1的累乘,但栈地址的错误导致函数无法正常返回。

修复后的代码(保留原结构与注释)

AREA Reset, CODE, READONLY
    ENTRY
SRAM_BASE EQU 0x20000000  ; 修改为Cortex-M系列通用SRAM起始地址,需根据实际芯片调整
    EXPORT Reset_Handler

Reset_Handler
    ; Set the stack memory location.
    LDR sp, =SRAM_BASE + 0x1000  ; 增大栈空间,避免溢出风险
    ; Pass the function parameter n value as 10 using the MOV command to the register that holds the parameter.
    MOV r0, #10


    ; Insert the code that calls the function to calculate factorial. The function name is CalcFacto in this case.

BL CalcFacto 

; Verify the returned value using the register that received the value, and exit the program.

stop B stop
    

CalcFacto
        ; while callee-saved registers are used to store values that must be preserved and include r4-r11 and lr.
        ; Save r4 and lr registers that will be used for calculation on the stack using stack operation commands.

    STMFD sp!, {r4, lr}
    MOV r4, #1 ; n = 0 , n! = 1
    CMP r0, #0 ; compare if n value is 0

sub_loop   ; perform multiplication operation using loop until n value becomes 0

        ; store the multiplication result in r4
    MULGT r4, r4, r0 

        ; Compare if the value obtained by subtracting 1 from the n value is greater than 0.
    SUBGTS r0, r0, #1

        ; Branch to loop if the n value is greater than 0
    BGT sub_loop

        ; Return the result value as per AAPCS using r0 and r1 registers.
    MOV r0,r4

        ; At the end of the function, restore the value of the r4 register, and store the lr register value as PC to return.
    LDMFD sp!, {r4, pc}

    END 

关键修复说明

  1. 修正SRAM地址:将SRAM_BASE改为0x20000000(多数Cortex-M芯片的SRAM起始地址),如果使用其他架构芯片,需替换为对应硬件的可写SRAM起始地址。
  2. 增大栈空间:将栈起始地址从SRAM_BASE + 100改为SRAM_BASE + 0x1000,避免栈溢出风险(原100字节空间虽足够,但预留更多空间更稳妥)。
  3. 正常返回逻辑:执行完CalcFacto后跳回stop B stop是预期的程序终止逻辑,并非错误,用于让程序停在断点处方便查看结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:32:48