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

ARM7TDMI参数传递问题:栈指针越界报错排查

问题分析与解决

代码重现

.data

CHAR_TO_FIND:     .byte   'A'
STRING_DATA:      .asciz  "HELLO ARM7"
STRING_LENGTH:    .word   10

.text

ldr r0 ,= STRING_DATA
ldr r1 ,= CHAR_TO_FIND
ldrb r1 , [r1]
mov r2 , #10

stmfa sp! , {r0 , r2}
bl char_find
swi 0x11

char_find:
ldmfa sp! , {r3 , r4}

错误原因

出现“stack pointer moved beyond stack frame”的核心原因是栈操作不匹配,且未处理bl指令自动压入的返回地址:

  1. 执行stmfa sp! , {r0 , r2}时,栈中压入2个32位寄存器(共8字节),SP指向栈顶的r2。
  2. 执行bl char_find时,ARM硬件会自动将当前返回地址(LR寄存器的值)压入栈,此时栈中共有3个32位元素:[r0][r2][LR],SP指向LR。
  3. 进入char_find后,仅用ldmfa sp! , {r3 , r4}弹出2个元素,SP仅回退8字节,栈中残留LR的值。函数返回后,主程序SP未回到压栈前的初始位置,后续栈操作会破坏栈帧结构,触发调试器的栈指针越界检测。

解决方法

方法1:匹配栈操作数量,正确处理返回地址

在char_find中弹出所有压入栈的元素(包括bl自动压入的LR),通过LR返回:

char_find:
    ldmfa sp! , {r3 , r4, lr}  ; 弹出r0→r3,r2→r4,LR→lr
    ; 此处编写字符查找逻辑
    mov pc, lr  ; 跳回主程序

操作后SP会回到主程序压栈前的位置,栈帧恢复正常。

方法2:遵循ARM调用约定,使用帧指针管理栈帧

建立函数栈帧,通过帧指针(FP)访问主程序传入的参数,避免直接弹出导致的栈混乱:

char_find:
    stmfa sp!, {fp, lr}  ; 保存旧帧指针和返回地址
    mov fp, sp           ; 设置新帧指针,绑定当前栈帧
    ldr r3, [fp, #8]     ; 通过帧指针偏移获取主程序压入的r0
    ldr r4, [fp, #12]    ; 获取主程序压入的r2
    ; 此处编写字符查找逻辑
    ldmfa sp!, {fp, pc}  ; 恢复帧指针,加载返回地址完成返回

这种方式贴合ARM标准调用规范,栈帧结构清晰,不易出错。

额外建议

ARM7通常使用满递减栈(FD),建议将stmfa/ldmfa替换为stmfd/ldmfd,更贴合通用调用约定,减少栈管理混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:12:35