ARM硬件架构 程序员

ARM汇编之解惑条件标志,条件码,条件执行

2018-08-04  本文已影响0人  赵国开

什么是条件执行(Conditional execution),它的机理是,根据运算结果更新的条件标志(condition flags),来判断指令的条件码(Condition code)是否符合条件,符合条件就执行,不符合条件则不执行。

A32/T32指令可以根据之前汇编指令更新的条件标志,来带条件的执行当前的汇编指令。为了让汇编指令带条件的执行,需要为汇编指令增加条件码后缀,这样就可以让处理器基于条件标志来测试是否需要执行该指令,如果条件测试不符,指令不会被执行,也不会影响其他任何标志,更不会产生异常,但是由于仍然占用了一个流水线空间,会消耗一个指令周期,除此之外什么也不会发生。


条件标志(condition flags)

总共有四个条件标志 N, Z, C, V,A32/T32中可存储更新到APSR寄存器最高的4个位置。大致示意图如下:


image.png

大部分的A32汇编指令编码中也会包含这四个位,而16位的T32指令大部分没有这些,所以不能带条件的执行,16位的指令编码带有的信息有限通常不会包含这四个位。

下面我们来说说,什么情况下这四个位会被置位/清除

条件标志 置位/清除
N 当运算的结果为负数的话置位,其他情况清0
Z 当运算的结果为0的话置位,其他情况清0
C 当运算的结果产生进位或者减法运算没有借位的话置位,其他情况清0
V 当运算的结果产生溢出的话置位,其他情况清0

例子1

ldr r1,=0xffffffff
ldr r2,=0x2
adds r3,r1,r2

例子2

mov r2,#3
mov r1,#1
subs r3,r2,r1;r3 = r2 - r1

例子:

ldr r1,=0x7fffffff
ldr r2,=0x2
adds r3,r1,r2

例子:

mov r1,#-1
mov r2,#-2
adds r3,r1,r2

例子:

mov r1,#0
mov r2,#0
adds r3,r1,r2

更新条件标志

例子:

ldr r1,=0x7fffffff
ldr r2,=0x2
adds r3,r1,r2
bvc stop
nop
nop
nop

stop b stop

下图是上面程序运行之后,条件标志更新结果:

image.png

因此接下来你要用合适的条件码来对操作结果进行判断,比如你明确r1,r2是有符号数,你要判断有符号的加法是否溢出,你就需要对V位进行判断,如例子中的vc条件码。

备注:CMP, CMN,TEQ, TST这几条指令总是会更新条件标志位。他们没有S后缀的格式。如果带条件执行的指令没有被执行,它不会影响条件标志。

条件码(Condition code)

所有支持的条件码(下图第一列)及含义如下图所示

image.png

例子:

    mov r2,#6
    ldr r1,=0x7fffffff
    subs r3,r2,r1;r3 = r2 - r1
    bgt stop
    nop
    nop
    nop 
stop b stop

比较指令

他们的语法格式如下

CMP{cond} Rn, Operand2;Rn - Operand2 操作类似SUBS(除了扔掉运算结果)
CMN{cond} Rn, Operand2;Rn + Operand2 操作类似ADDS(除了扔掉运算结果)
TEQ{cond} Rn, Operand2;Rn EOR Operand2  操作类似EORS(除了扔掉运算结果)
TST{cond} Rn, Operand2;Rn AND Operand2  操作类似ANDS(除了扔掉运算结果)

备注:对TEQ和TST来说不会影响到V标志,N位和Z位会根据操作结果会被更新,Operand2移位操作也可能会影响到C位。而CMP和CMN则根据运算结果都有可能会被影响到。

例子:

    mov r1,#-1
    mov r2,#0
    tst r1,r2
    beq stop
    nop
    nop
    nop

stop b stop

为什么需要条件执行

C语言描述的算法如下:

int gcd(int a, int b)
{
    while (a != b)
      {
        if (a > b)
            a = a - b;
        else
            b = b - a;
      }
    return a;
}

如果用条件分支实现,代码如下:

gcd     CMP      r0, r1
        BEQ      end
        BLT      less
        SUBS     r0, r0, r1  ; could be SUB r0, r0, r1 for A32
        B        gcd
less
        SUBS     r1, r1, r0  ; could be SUB r1, r1, r0 for A32
        B        gcd
end

如果用带条件指令的条件执行,代码如下:

gcd
        CMP      r0, r1
        SUBGT    r0, r0, r1
        SUBLE    r1, r1, r0
        BNE      gcd

跟用分支执行的比较,该代码长度更小,而且执行的也更快。


参考资料

【1】DUI0801I_armasm_user_guide
【2】ARM Development Tools
【3】ARM Assembly Language_ Fundamentals and Techniques (2nd ed.)
【4】DDI0487C_a_armv8_arm

上一篇 下一篇

猜你喜欢

热点阅读