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

ARM汇编迭代数组时为何给寄存器加#4而非#1推进地址?

ARM汇编数组遍历地址偏移问题

你分析的这段是ARM架构下实现整数数组累加求和的汇编代码,完整代码如下:

RES:       .word 0
N:         .word 5
NUM1:      .word 3, -17, 27, -12, 322

LDR r1, N
ADR r2, NUM1
MOV r0, #0

LOOP:      LDR r3, [r2]
           ADD r0, r0, r3
           ADD r2, r2, #4
           SUB r1, r1, #1
           CMP r1, #0
           BGT LOOP
           STR r0, RES

ADD r2, r2, #4这行的作用是把指向数组当前元素的指针移动到下一个元素,不能替换成ADD r2, r2, #1的原因非常明确:

  • ARM、x86等绝大多数通用CPU都采用字节编址规则:内存中每个独立地址对应1字节(8bit)的存储空间,地址数值加1,只会向后移动1个字节的位置,不会直接跳到下一个同类型数据。
  • 代码中.word伪指令定义的是32位(即4字节)长度的数据:不管是存结果的RES、存数组长度的N,还是NUM1数组里的每个整数,单个元素都要占用连续4个字节的内存空间。
    举个实际排布的例子:如果NUM1标签对应的起始内存地址是0x2000,数组各元素的地址分布为:
    • 第一个元素3:占用0x2000~0x2003共4个地址
    • 第二个元素-17:占用0x2004~0x2007共4个地址
    • 后续每个元素的起始地址,都比上一个元素的起始地址高4
  • 循环里的LDR r3, [r2]指令,会从r2存储的地址开始,读取连续4字节的完整32位字数据存入r3寄存器。如果每次只给r2加1,下一次读取的起始地址仅向后偏移1字节,读到的是上一个元素残留的3字节和下一个元素首字节拼接出的错误值,根本不是目标数组元素。
  • 只有少数教学用的简化虚拟CPU会采用字编址模式,地址加1就对应跳过一个字长的数据,这种场景下才会写偏移1的逻辑,但真实商用架构都不采用这种编址方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:06:55