ARM汇编中的负寄存器及LDR指令有效地址计算疑问
关于ARM汇编指令
LDR r0,[r2,‐r3, LSL #1]的负寄存器疑问解答 嘿,我来帮你理清这个问题——当初啃Alan Clements的ARM汇编书时,我也在寻址模式上卡过壳,咱们一步步拆解来看:
核心疑问解答:-r3确实是r3寄存器值的负数
这条指令属于ARM的基址变址寻址,有效地址的计算逻辑非常明确:
- 先对r3执行逻辑左移1位操作(
LSL #1),相当于把r3的值乘以2; - 对移位后的结果取负;
- 把这个负数值和r2中存储的基地址相加,最终得到要访问的内存有效地址。
用公式表示就是:有效地址 = r2的值 - (r3的值 << 1)
举个实际数值的例子:如果r2=0x1000,r3=0x0004,那么移位后r3变成0x0008,取负是-0x0008,有效地址就是0x1000 - 0x0008 = 0x0FF8,LDR r0会把0x0FF8地址处的内容加载到r0寄存器中。
ARM汇编中“负寄存器”的相关知识点
其实ARM里并没有专门的“负寄存器”硬件概念,它只是寻址偏移中的一种写法,本质是用寄存器值的负数作为偏移量,常见场景和规则如下:
- 核心用途:用来访问基地址之前的内存区域,比如数组反向遍历、从结构体中向前访问成员,或者某些需要回退地址的操作。
- 支持的寻址模式:这种负偏移写法适配大多数基址变址寻址模式,包括:
- 前变址:
LDR r0, [r2, -r3]!(感叹号表示执行后把计算出的地址写回r2) - 后变址:
LDR r0, [r2], -r3(先访问r2指向的地址,再把r2 - r3的值写回r2)
- 前变址:
- 注意事项:这里的取负是数值层面的临时减法运算,不会修改原寄存器r3的值;如果r3存储的是有符号数,取负会遵循ARM的算术规则,但寻址时一般按无符号地址处理。
内容的提问来源于stack exchange,提问作者Deik




