4.3.2. ADD、SUB、RSB、ADC、SBC 和 RSC

加法、减法和反向减法,均可带进位或不带进位。

另请参阅并行加法和减法

语法

op{S}{cond} {Rd}, Rn, Operand2
op{cond} {Rd}, Rn, #imm12               ; Thumb-2 ADD and SUB only

其中:

op

是下列项之一:

ADD

加法。

ADC

带进位加法。

SUB

减法。

RSB

反向减法。

SBC

带进位减法。

RSC

带进位反向减法(仅 ARM)。

S

是一个可选的后缀。 如果指定 S,则会更新运算结果的条件代码标记(请参阅条件执行)。

cond

是一个可选的条件代码(请参阅条件执行)。

Rd

是目标寄存器。

Rn

是存放第一个操作数的寄存器。

Operand2

是一个灵活的第二操作数。 有关此选项的详细信息,请参阅灵活的第二操作数

imm12

可为 0-4095 范围内的任意值。

用法

ADD 指令将 Rn 中的值与 Operand2 中的值相加。

SUB 指令从 Rn 中的值中减去 Operand2 中的值。

RSB(反向减法)指令可从 Operand2 中的值减去 Rn 中的值。 这是很有用的,因为有了该指令,Operand2 的选项范围就会更大。

您可利用 ADCSBCRSC 来进行合成多字运算(请参阅多字算法示例)。

ADC(带进位加法)指令将 Rn 中的值和 Operand2 中的值相加(带进位标记)。

SBC(带进位减法)指令可从 Rn 中的值中减去 Operand2 中的值。 如果清除进位标记,则结果将减 1。

RSC(带进位反向减法)指令可从 Operand2 中的值中减去 Rn 中的值。 如果清除进位标记,则结果将减 1。

在某些情况下,汇编器可能会进行替换指令。 阅读反汇编列表时请注意这一点。 有关详细信息,请参阅指令替换

在 Thumb-2 指令中使用 pc

这些指令中的大多数都不能将 pc (r15) 用于 Rd 或任何操作数。

但也有例外,可以在 ADDSUB 指令中,将 pc 用于 Rn,这要求常数值 Operand2 要在 0-4095 范围内,且不能有 S 后缀。 这些指令可用于生成 pc 相对地址。 在上述情况下,pc 值的位 [1] 都会为 0,以使计算时基址始终为字对齐。

另请参阅SUBS pc, lr

另请参阅ADR

在 ARM 指令中使用 pc

如果将 pc (r15) 用作 Rn,则所用的值为指令地址加 8。

如果将 pc 用作 Rd,则:

  • 代码将跳转到与结果相对应的地址执行。

  • 如果使用 S 后缀,则当前模式的 SPSR 会复制到 CPSR。 您可利用此机制从异常中返回(请参阅《开发指南》中的第 6 章 处理处理器异常)。

另请参阅ADR

Caution

在用户模式和系统模式下,若是将 pc 用作 Rd,则不要使用 S 后缀。 此类指令的结果不可预知,而且汇编器在汇编时不会发出警告。

在所有由寄存器控制移位的数据处理指令中,都不能将 pc 用于 Rd 或任何操作数(请参阅灵活的第二操作数)。

条件标记

如果指定了 S,则这些指令将会根据结果来更新 N、Z、C 和 V 标记。

16 位指令

这些指令的下列形式可用于 Thumb-2 之前的 Thumb 代码中,在 Thumb-2 代码中使用时为 16 位指令:

ADDS Rd, Rn, #imm

imm 范围为 0-7。RdRn 必须都是 Lo 寄存器。

ADDS Rd, Rn, Rm

RdRnRm 必须都是 Lo 寄存器。

ADD Rd, Rd, Rm

ARMv6 及更低版本: Rd 和/或 Rm 必须是 Hi 寄存器。 ARMv6T2 及更高版本: 无此限制。

ADDS Rd, Rd, #imm

imm 范围为 0-255。Rd 必须是 Lo 寄存器。

ADCS Rd, Rd, Rm

RdRnRm 必须都是 Lo 寄存器。

ADD SP, SP, #imm

imm 范围为 0-508,字对齐。

ADD Rd, SP, #imm

imm 范围为 0-1020,字对齐。 Rd 必须是 Lo 寄存器。

ADD Rd, pc, #imm

imm 范围为 0-1020,字对齐。 Rd 必须是 Lo 寄存器。 在此指令中,pc 的位 [1:0] 将为 0。

SUBS Rd, Rn, Rm

RdRnRm 必须都是 Lo 寄存器。

SUBS Rd, Rn, #imm

imm 范围为 0-7。RdRn 必须都是 Lo 寄存器。

SUBS Rd, Rd, #imm

imm 范围为 0-255。Rd 必须是 Lo 寄存器。

SBCS Rd, Rd, Rm

RdRnRm 必须都是 Lo 寄存器。

SUB SP, SP, #imm

imm 范围为 0-508,字对齐。

RSBS Rd, Rn, #0

RdRn 必须都是 Lo 寄存器。

示例

    ADD     r2, r1, r3
    SUBS    r8, r6, #240        ; sets the flags on the result
    RSB     r4, r4, #1280       ; subtracts contents of r4 from 1280
    ADCHI   r11, r0, r3         ; only executed if C flag set and Z
                                ; flag clear
    RSCSLE  r0,r5,r0,LSL r4     ; conditional, flags set

不正确的示例

    RSCSLE  r0,pc,r0,LSL r4    ; pc not permitted with register
                                ; controlled shift

多字算法示例

下面两个指令将 r2r3 中包含的 64 位整数与 r0r1 中的包含的 64 位整数相加,并将结果存入 r4r5 中。

    ADDS    r4, r0, r2    ; adding the least significant words
    ADC     r5, r1, r3    ; adding the most significant words

下面的指令可完成 96 位整数的减法:

    SUBS    r3, r6, r9
    SBCS    r4, r7, r10
    SBC     r5, r8, r11

为了便于理解,对于多字值,上面的示例使用的是连续的寄存器。 实际上并没有这种要求。 例如,下面的示例也完全有效:

    SUBS    r6, r6, r9
    SBCS    r9, r2, r1
    SBC     r2, r8, r11
Copyright © 2002-2008 ARM Limited. All rights reserved.ARM DUI 0204IC
Non-Confidential