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

ARM汇编STR指令写内存时超8位数值存储错误问题排查

问题原因

你出现这个问题的核心原因是ARM访存指令的位宽使用错误,且地址自增步长和指令位宽不匹配:

  • ARM架构中,无后缀的LDR/STR是32位字访存指令,执行时会连续读写目标地址起始的4个字节内存,而非1个字节。
  • 你代码中设置的地址后自增偏移为#1,和32位字访存要求的4字节步长完全不匹配。
  • 你观测到的121正好是377(十六进制为0x00000179)的最低8位值(0x79):Keil仿真默认使用小端存储模式,执行STR写入32位值时,会把最低字节存在目标地址、次低字节存在目标地址+1位置,剩下两个高位字节存在后续地址。你在内存面板按字节查看时,首先看到的目标地址位置的121就是被截断的低8位,高位的1被写到了下一个地址,之前数值小于256时,高位全为0,低8位正好等于完整数值,所以没有暴露出问题。

另外你的加载指令也存在同样的问题:用LDR做32位加载却每次地址只加1,本质是做非对齐字读取,只是因为之前读取的数值小于256,周边内存字节为0,才没出现计算错误。

解决方法

根据你的实际存储需求二选一即可:

  • 如果你需要逐字节处理、存储8位数据(值域0-255):将所有访存指令替换为带字节操作后缀的LDRB/STRB,保持步长1不变。注意377超出8位值域,用这种方式存储会被截断为低8位121,如果需要保留完整计算结果请选第二种方案。
    修正后的代码段:
    LDRB R6, [R3],#1 ; 加载1字节到R6,高位自动清零
    LDRB R7, [R4],#1 ; 加载1字节到R7,高位自动清零
    
    ADD R5, R6, R7   ; 计算两数之和
    STRB R5, [R12],#1; 存储R5低8位到内存,地址自增1
    
  • 如果你需要存储完整的32位计算结果(支持大于255的值):保留LDR/STR字访存指令,将地址自增步长从1改为4,同时保证R3、R4、R12的初始地址是4字节对齐(地址值可被4整除),避免触发对齐异常。
    修正后的代码段:
    LDR R6, [R3],#4 ; 加载32位字到R6,地址自增4
    LDR R7, [R4],#4 ; 加载32位字到R7,地址自增4
    
    ADD R5, R6, R7  ; 计算两数之和
    STR R5, [R12],#4; 存储R5完整32位值到内存,地址自增4
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:51:16