| |
如果需要,ARM的任何数据处理指令都能通过增加S操作码来设置条件码。对于比较、测试指令操作,其主要作用就是设置条件码,因此可不用增加S操作码,但对所有其他数据处理指令必须通过增加S操作码来指明。例如,下面代码完成2个数的64位加法,一个数存于[R1,R0],另一个数存于[R3,R2],用C条件码标志位存立即数进位:
ADDS R2,R2,R0 ;32位进位输出到C
ADC R3,R3,R1 ;再加到高位字中
由于操作码的S扩展能控制指令是都修改条件码,所以适合的时候,需要在指令序列中把条件码保护起来,如在中断的情况下。
数据处理指令加了S后,算数操作根据算术运算的结果设置所有标志位。逻辑“或”传送操作不产生有意义的C或V值,他们根据结果设置N和Z,保留V。
1)条件执行
ARM指令集不同寻常的特征是每条指令都可以是条件执行的。条件转移是绝大多数指令集的标准特征,但ARM将条件执行扩展到所有指令,包括监控调用和协处理器指令。条件域cond占据32位指令域的高四位,如图所示。
条件域共有16个值,每个值都根据CPSR中的N、Z、C和V的标志位的值来确定指令执行还是跳过。
一条指令本来是用于跳过其后的几条指令,但如果利用ARM指令集所有ARM指令都可执行这一特点,则给予指令后的ARM指令以相反的条件,转移将被忽略。
例如:
CMP R0,#5
BEQ BYPASS ;如果R0≠5
ADD R1,R1,R0 ;则R1=R1+R0-R2
SUB R1,R1,R2 ;
BYPASS
这可替代为:
CMP R0,#5 ;如果R0≠5
ADDNE R1,R1,R0 ;则R1=R1+R0-R2
SUBNE R1,R1,R2 ;
…
新的指令序列比原先的既短小又快速。如果被跳过的指令序列并不进行复杂的操作,使用条件执行都要比使用转移好。因为ARM转移指令一般要用3个周期来执行,所以上面例子中采用3条指令的方法。如果代码充分优化,那么是使用条件执行还是转移,需要根据代码动态行为的测量来决定。
有时巧妙地使用条件,可写出非常简练的代码。例如:
;if((a==b)&&(c==d))e++
CMP R0,R1
CMPEQ R2,R3
ADDEQ R4,R4,#4
注意:如果第一个比较发现操作数不同,则第二个比较指令和后面加1指令也将跳过。由于第二个比较指令使用了条件执行,从而实现了if语句的逻辑“与”。
2)条件转移
在程序中可通过条件码的使用让微处理器决定是否进行转移。例如,为了实现循环操作,往往需要转移回到循环的开始,但是这种转移应该仅发生在执行到所需的循环次数之前,这以后转移应被跳过。这时,在转移指令后加上合适的条件,就可恨容易地实现该功能。
条件转移还可用来控制循环的退出。这时,转移与条件码紧密相连,只有当条件码的值满足条件时,相应的转移才被执行。一种典型的循环控制指令序如下所示:
MOV R0,#0 ;计数器初始化
LOOP …
ADD R0,R0,#1 ;循环计数器加1
CMP R0,#10 ;与循环的限制比较
BNE LOOP ;如果不相等则返回
… ;否则循环中止
例中给出了条件转移是BNE,即“不等则转移”条件转移的形式共有十几种,表中同一栏内的一对条件的涵义相同,二进制代码也相同,但两者都是有用的,因为在特定的环境中每一种条件都可能使得汇编语言源代码的编译更加容易。在表中提到有符号数和无符号数的比较时,并不是说指令可区分有符号数和无符号数,知识说明本条指令可对有符号数进行大小比较,比较的结果是正确的;当操作数是有符号数时,结果不一定正确。
凌阳教育,专注嵌入式人才培养多年,完善的培养方案,强大的师资,合理的课程安排,成功从小白蜕变为嵌入式工程师。想了解凌阳教育,或者获得更多嵌入式学习资料的免费下载,请点击www.sunplusedu.com访问凌阳教育官网