ARM汇编基础

ARM 154浏览


ARM体系平台手册笔记07

ADC指令

ADC指令格式

        31      28 27 26 25 24 23 22 21 20 19       16 15       12 11               0
          cond     0   0  I  0  1  0  1  S       Rn             Rd       shifter_operand
    ADC(添加进位)添加两个值和进位标志。第一个值来自一个寄存器。第二个值可以是立即值,也可以是来自寄存器的值,并且可以在添加之前进行移位。 ADC可以根据结果选择更新条件代码标志

    语法:
        ADC{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
    <cond>是执行指令的条件。条件在第A3-3页的条件字段中定义。如果省略<cond>,则使用AL(always)条件。

    S 使指令中的S位(位[20])置1,并指定该指令更新CPSR。
    如果省略S,则S位被设置为0,CPSR不被指令改变。当指定S时,可能会发生两种类型的CPSR更新:
    如果<Rd>不是R15,则根据添加的结果设置N和Z标志,并根据是否生成加法来设置C和V标志一个进位(无符号溢出)和一个带符号的溢出。 CPSR的其余部分保持不变。
    如果<Rd>为R15,当前模式的SPSR将复制到CPSR。如果在用户模式或系统模式下执行,则该形式的指令为UNPREDICTABLE,因为这些模式没有SPSR
        <Rd> 指定目标寄存器。
        <Rn> 指定包含第一个操作数的寄存器。
        <shifter_operand>
指定第二个操作数。该操作数的选项在寻址模式1 - 第A5-2页的数据处理操作数中有所描述,包括每个选项如何使I位(位[25])和shifter_operand位(位[11:0])成为在指令中设置。
    如果I位为0,shiftter_operand的位[7]和位[4]都为1,则该指令不是ADC。相反,请参阅扩展第A3-32页上的指令集,以确定它是哪个指令。

CPU执行的操作

    if ConditionPassed(cond) then
        Rd = Rn + shifter_operand + C Flag
        if S == 1 and Rd == R15 then
            if CurrentModeHasSPSR() then
                CPSR = SPSR
            else UNPREDICTABLE
        else if S == 1 then
            N Flag = Rd[31]
            Z Flag = if Rd == 0 then 1 else 0
            C Flag = CarryFrom(Rn + shifter_operand + C Flag)
            V Flag = OverflowFrom(Rn + shifter_operand + C Flag)

举例

        使用ADC来合成多字加法。如果寄存器对R0,R1和R2,R3保持64位值(其中R0和R2保持最低有效字),
        以下指令将64位和值保留在R4,R5:
            ADDS R4,R0,R2
            ADC R5,R1,R3
            如果第二条指令从ADC R5,R1,R3更改成ADCS R5,R1,R3    ,标志的结果值表示:
                N 64位加法产生不良结果。
                C 发生无符号溢出。
                V 发生有符号溢出。
                Z 最高32位全部为零。


    以下指令在R0:
        ADCS R0,R0,R0上产生带有扩展操作的1位旋转左移(通过进位标志进行33位旋转)
        R0 + R0 + C + Flag ==> R0 << 1 + C Flag ==> LSR R0,#1

ADD指令

ADD指令格式

    31      28 27 26 25 24 23 22 21 20 19       16 15       12 11               0
        cond   0  0 I  0   1  0  0  S       Rn       Rd          shifter_operand
    ADD增加了两个值。第一个值来自一个寄存器。
    第二个值可以是立即值,也可以是来自寄存器的值,并且可以在添加之前进行移位。 ADD可以根据结果选择更新条件代码标志。
    语法
        ADD {<cond>} {S} <Rd>,<Rn>,<shifter_operand>

    其中:<cond>是执行指令的条件。第A3-3页上的条件字段。如果省略<cond>,则使用AL(always)条件。
    S 使指令中的S位(位[20])置1,并指定该指令更新CPSR。如果省略S,则S位被设置为0,CPSR不被指令改变。
当指定S时,可能会发生两种类型的CPSR更新:
    如果<Rd>不是R15,则根据添加的结果设置N和Z标志,并根据是否生成加法来设置C和V标志一个进位(无符号溢出)和一个带符号的溢出。 CPSR的其余部分保持不变。
    如果<Rd>为R15,当前模式的SPSR将复制到CPSR。如果在用户模式或系统模式下执行,则该指令的形式为UNPREDICTABLE,因为这些模式没有SPSR。
        <Rd> 指定目标寄存器。
        <Rn> 指定包含第一个操作数的寄存器。
        <shifter_operand> 指定第二个操作数。该操作数的选项在寻址模式1 - 第A5-2页的数据处理操作数中有所描述,包括每个选项如何使I位(位[25])和shifter_operand位(位[11:0])成为在指令中设置。
    如果I位为0,shiftter_operand的位[7]和位[4]为1,则指令不为ADD。相反,请参阅扩展第A3-32页上的指令集,以确定它是哪个指令。

架构版本 全部
异常 无

CPU执行的操作

    if ConditionPassed(cond) then
        Rd = Rn + shifter_operand
        if S == 1 and Rd == R15 then
            if CurrentModeHasSPSR() then
                CPSR = SPSR
            else UNPREDICTABLE
        else if S == 1 then
            N Flag = Rd[31]
            Z Flag = if Rd == 0 then 1 else 0
            C Flag = CarryFrom(Rn + shifter_operand)
            V Flag = OverflowFrom(Rn + shifter_operand)

举例

    使用ADD将两个值一起添加。
    要增加Rx中的寄存器值,请使用:
        ADD Rx,Rx,#1
    您可以通过以下方式执行Rx乘以2^n + 1到Rd:
        ADD Rd,Rx,Rx,LSL #n
    要形成PC相对地址,请使用:
        ADD Rd,PC,#offset,其中偏移量必须是所需地址与PC中保存的地址之间的差值,其中PC是ADD指令本身的地址加8字节。